import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class AES256 {
/**
* 암호화 기법 중 AES256 방법을 소개
* 대표적인 양방향 암호화
* 대칭키: 암호화, 복호화에 동일한 키가 사용 됨
* 비대칭키: 암호화, 복호화의 다른 키가 다름
*/
// 16바이트(128비트) IV(Initialization Vector). CBC 모드에서 첫 블록을 암호화할 때 사용.
private static final String IV = "1234567890abcdef";
// 32바이트(256비트) 비밀 키. AES256 암호화/복호화에 사용됩니다.
private static final String secretKey = "12345678ABCDEFGHabcdefgh12345678";
/**
* Cipher 객체를 생성하고 초기화하는 메서드
*
* @param cipherMode 암호화(Cipher.ENCRYPT_MODE) 또는 복호화(Cipher.DECRYPT_MODE) 모드 지정
* @return 초기화된 Cipher 객체
* @throws Exception Cipher 생성 또는 초기화 중 발생할 수 있는 모든 예외 처리
*/
public static Cipher createdAES256(int cipherMode) throws Exception {
// AES 알고리즘, CBC 모드, PKCS5 패딩을 지정하여 Cipher 인스턴스 생성
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// 비밀 키(secretKey)를 UTF-8 바이트 배열로 변환
byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
// IV(초기화 벡터)를 UTF-8 바이트 배열로 변환하여 IvParameterSpec 객체 생성
IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8));
// 키 바이트 배열과 "AES" 알고리즘 이름을 사용하여 SecretKeySpec 객체 생성
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
// 생성한 Cipher 객체를 지정된 모드(암호화/복호화), 비밀 키, IV로 초기화
cipher.init(cipherMode, secretKeySpec, ivParameterSpec);
return cipher;
}
/**
* 평문(plainText)을 AES256으로 암호화하고 Base64로 인코딩합니다.
*
* @param plainText 암호화할 평문 문자열
* @return Base64로 인코딩된 암호문 문자열
* @throws Exception 암호화 중 발생할 수 있는 모든 예외 처리
*/
public static String encrypt(String plainText) throws Exception {
// 암호화 모드로 초기화된 Cipher 객체 가져오기
Cipher cipher = createdAES256(Cipher.ENCRYPT_MODE);
// 평문 문자열을 UTF-8 바이트 배열로 변환하여 암호화 실행
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
// 암호화된 이진 데이터를 Base64 인코딩하여 안전한 문자열로 변환 후 반환
return Base64.getEncoder().encodeToString(encryptedBytes);
}
/**
* Base64로 인코딩된 암호문(encryptedText)을 복호화하여 평문으로 되돌립니다.
*
* @param encryptedText 복호화할 Base64 인코딩된 암호문
* @return 복호화된 평문 문자열
* @throws Exception 복호화 중 발생할 수 있는 모든 예외 처리 (Base64 디코딩 실패 포함)
*/
public static String decrypt(String encryptedText) throws Exception {
// 복호화 모드로 초기화된 Cipher 객체 가져오기
Cipher cipher = createdAES256(Cipher.DECRYPT_MODE);
// Base64로 인코딩된 문자열을 이진 바이트 배열로 디코딩
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
// 디코딩된 바이트 배열을 복호화 실행
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
// 복호화된 바이트 배열을 UTF-8 문자열로 변환하여 반환
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
/**
* 메인 메서드: 암호화 및 복호화 과정을 테스트합니다.
* @param args 프로그램 인자 (사용되지 않음)
* @throws Exception 테스트 과정 중 발생할 수 있는 모든 예외 처리
*/
public static void main(String[] args) throws Exception {
String plainText = "Hello~~";
System.out.println("plainText :: " + plainText);
String encrypted = encrypt(plainText);
System.out.println("encrtyped :: " + encrypted);
String decrypted = decrypt(encrypted);
System.out.println("decrypted :: " + decrypted);
}
}[Java] AES256 AES/CBC/PKCS5Padding
2019. 3. 8. 10:25