이번 포스팅에서는 AES 알고리즘을 통해 문자열을 Base64 인코딩/디코딩 하는 방법에 대해 포스팅 하겠습니다.
Java에서는 JCE (Java Cryptography Extension) 를 통해 암호화에 필요한 클래스를 제공하고 있습니다.
AES 알고리즘은 128, 192, 256bit 를 지원하지만, 기본으로 설치되는 JDK 를 통해 AES 알고리즘을 사용하는 경우
정책상 128bit 밖에 사용 할 수 없습니다. (기본 제공하는 각 암호화 알고리즘의 Limit 키사이즈는 아래 링크 참고)
128bit 를 사용하지 않는경우 아래와 같은 Exception 이 발생합니다.
java.security.InvalidKeyException: Illegal key size or default parameters
192, 256 bit 방식을 사용하기 위해선 별도로 JCE Unlimited Strength Jurisdiction Policy Files 을
오라클 홈페이지에서 다운받아 사용해야 합니다.
JCE에 포함된 javax.crypto 패키지는 암호화에 필요한 클래스를 제공하고 있습니다.
해당 패키지에서 제공하는 클래스를 통해 데이터를 암호화/복호화 할 수 있습니다.
또한, 부가적으로 아래 코드에서 javax.xml.bind 패키지의 DatatypeConverter 클래스를 사용한 이유는
JAXB 에서 XML & Java 간 데이터를 표현할때 필요한 데이터를 변환해주는 클래스를 사용하여
Base64 로 인코딩/디코딩 해주는 메서드를 사용 하였습니다.
실제 제가 근무하는 XX은행 프레임워크에서는 AES256 알고리즘을 사용하여 데이터를 암호화 하고 있습니다.
//keySize에 따른 AES 암호화 키 생성 public static String generateBase64Key(int keySize) throws Exception { KeyGenerator generator = KeyGenerator.getInstance("AES"); generator.init(keySize); Key secretKey = generator.generateKey(); return DatatypeConverter.printBase64Binary(secretKey.getEncoded()); } //문자열을 key를 통해 암호화 하고 base64 로 인코딩 public static String encryptAES128(byte[] key, String message) throws Exception { SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec); byte[] encrypted = cipher.doFinal(message.getBytes()); //encrypt String encodeString = DatatypeConverter.printBase64Binary(encrypted); //Converts an array of bytes into a string. return encodeString; } //base64로 인코딩된 key 를 통해 문자열 base64 인코딩 public static String encryptAES128(String base64Key, String message) throws Exception { return encryptAES128(base64DecodeKey(base64Key), message); } //key 를 통해 문자열 base64 디코딩 public static String decryptAES128(byte[] keys, String encrypted) throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException { SecretKeySpec keySpec = new SecretKeySpec(keys, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, keySpec); byte[] decodeBytes = DatatypeConverter.parseBase64Binary(encrypted); //Converts the string argument into an array of bytes. byte[] decryptBytes = cipher.doFinal(decodeBytes); //decrypt return new String(decryptBytes); } //base64로 인코딩된 key 를 통해 문자열 base64 디코딩 public static String decryptAES128(String base64Key, String encrypted) throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException { return decryptAES128(base64DecodeKey(base64Key), encrypted); } //base64로 인코딩된 key를 byte 배열로 디코딩 public static byte[] base64DecodeKey(String base64Key) { return DatatypeConverter.parseBase64Binary(base64Key); } //byte배열의 키를 base64로 인코딩 public static String base64EncodeKey(byte[] key) { return DatatypeConverter.printBase64Binary(key); }
마지막으로, 128bit 보다 강력한 256bit 를 사용하시길 권장합니다.
참고
[1] AES 알고리즘 - http://ko.wikipedia.org/wiki/%EA%B3%A0%EA%B8%89_%EC%95%94%ED%98%B8%ED%99%94_%ED%91%9C%EC%A4%80
[2] Base64 - http://ko.wikipedia.org/wiki/%EB%B2%A0%EC%9D%B4%EC%8A%A464
[3] Import Limits on Cryptographic Algorithms - http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#importlimits
'프로그래밍 > JAVA' 카테고리의 다른 글
WAS JMX 에러해결 방법 (0) | 2015.02.18 |
---|---|
String 클래스 깊숙히 이해하기 (3) | 2014.11.09 |
자바 IO&NIO 파일복사 (FileCopy) 방법 (0) | 2014.09.08 |
JOptionPane 클래스 (0) | 2013.08.31 |
JFileChooser 클래스 (0) | 2013.08.31 |