게으른 개발자의 끄적거림

AES 256 암호화, 복호화 방법

끄적잉 2023. 5. 22. 23:08
반응형

1. AES 256 암호화

- AES 256은 키가 256bit 즉 32바이트 문자열 이어야 합니다.

- 이 예제에서는 임의의 길이의 키 문자열을 받아서 랜덤 salt 를 첨가해서 해시하여 256bit 키를 생성합니다.

- 암호화 모드는 CBC를 사용하고, 길이를 일정하게 하는데 PKCS5 패딩을 사용합니다.

- salt를 사용하므로 동일한 값을 암호화 하더라도 암호된 값이 동일하지 않습니다.

- 결과값에는 salt와 iv값을 추가하여 Base64로 엔코딩 하여 반환합니다.

- Java 8에는 Base64 기능이 포함되어 있지만, 그 이전 버전의 JDK를 사용한다면 apache common codec 라이브러리 등을 사용하여 Base64 엔코딩 기능을 사용할 수 있습니다.

 

 

public static String encryptAES256(String msg, String key) throws Exception {

SecureRandom random = new SecureRandom();

byte bytes[] = new byte[20];

random.nextBytes(bytes);

byte[] saltBytes = bytes;

 

// Password-Based Key Derivation function 2

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

 

// 70000번 해시하여 256 bit 길이의 키를 만든다.

PBEKeySpec spec = new PBEKeySpec(key.toCharArray(), saltBytes, 70000, 256);

SecretKey secretKey = factory.generateSecret(spec);

SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

 

// 알고리즘/모드/패딩

// CBC : Cipher Block Chaining Mode

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

cipher.init(Cipher.ENCRYPT_MODE, secret);

AlgorithmParameters params = cipher.getParameters();

 

// Initial Vector(1단계 암호화 블록용)

byte[] ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();

byte[] encryptedTextBytes = cipher.doFinal(msg.getBytes("UTF-8"));

byte[] buffer = new byte[saltBytes.length + ivBytes.length + encryptedTextBytes.length];

System.arraycopy(saltBytes, 0, buffer, 0, saltBytes.length);

System.arraycopy(ivBytes, 0, buffer, saltBytes.length, ivBytes.length);

System.arraycopy(encryptedTextBytes, 0, buffer, saltBytes.length + ivBytes.length, encryptedTextBytes.length);

 

return Base64.getEncoder().encodeToString(buffer);

}

 

2. 암호화된 내용을 복호화

 

public static String decryptAES256(String msg, String key) throws Exception {

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

ByteBuffer buffer = ByteBuffer.wrap(Base64.getDecoder().decode(msg));

 

byte[] saltBytes = new byte[20];

buffer.get(saltBytes, 0, saltBytes.length);

byte[] ivBytes = new byte[cipher.getBlockSize()];

buffer.get(ivBytes, 0, ivBytes.length);

byte[] encryoptedTextBytes = new byte[buffer.capacity() - saltBytes.length - ivBytes.length]; buffer.get(encryoptedTextBytes);

 

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

PBEKeySpec spec = new PBEKeySpec(key.toCharArray(), saltBytes, 70000, 256);

 

SecretKey secretKey = factory.generateSecret(spec);

SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

 

cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes));

 

byte[] decryptedTextBytes = cipher.doFinal(encryoptedTextBytes);

 

return new String(decryptedTextBytes);

}

 

 

3. 실행예제

public class CryptoTest { public static void main(String[] args) throws Exception {

String plainText = "Hello, World!";

String key = "secret key";

 

System.out.println("MD5 : " + plainText + " - " + CryptoUtil.md5(plainText));

System.out.println("SHA-256 : " + plainText + " - " + CryptoUtil.sha256(plainText));

 

String encrypted = CryptoUtil.encryptAES256("Hello, World!", key);

System.out.println("AES-256 : enc - " + encrypted); System.out.println("AES-256 : dec - " + CryptoUtil.decryptAES256(encrypted, key));

  }

}

 

참조 : https://offbyone.tistory.com/286

 

자바 MD5, SHA-256, AES256 암호화 하기

java.security 라이브러리를 사용해서 MD5, SHA-256 으로 해시 하는 방법과 AES-256 으로 암호화 하고 복호화 하는 방법을 알아 봅니다. MD5와 SHA-256은 단뱡향 암호화로 비밀번호를 암호화 하거나 데이터

offbyone.tistory.com

 

반응형