java에서 일반적인 byte[] -> string -> byte[] 는 문제가 없으나
암호화된 값을 변형할 때는 원복되지 않는 버그가 있다고 한다..(확실치 않음)
해서 헥사 코드 값을 db에 저장해서 다시 불러와 복호화 하려하면
Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
Exception 발생.
이럴 땐 헥사 코드값을 저장해서 다시 복호화하려 하지 말고 아래와 같이 BASE64로 인코딩하고 디코딩해서
복호화 하는 방법을 쓴다.
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class Test{
private static final String key = "AES";
private static Cipher cipher;
private static SecretKeySpec skeySpec;
static{
try{
KeyGenerator kgen = KeyGenerator.getInstance( key );
kgen.init(128); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
skeySpec = new SecretKeySpec(raw, "AES");
cipher = Cipher.getInstance( key );
}catch( Exception e){
e.printStackTrace();
}
}
public static void main(String [] args){
try{
//원문
String str = "This sample program demonstrates how to use strong cryptography, which is available by default in most installations. ";
byte[] encrypted = Encrypt(str, skeySpec, cipher);
String sBase = new BASE64Encoder().encode(encrypted);
System.out.println("base64 Encoded 암호문 : " + sBase);
byte[] decrypted = Decrypt(new BASE64Decoder().decodeBuffer(sBase), skeySpec, cipher);
System.out.println("decrypt된 원문 : " + new String(decrypted));
}catch(Exception e){
e.printStackTrace();
}finally{
}
}
public static byte[] Encrypt(String data, SecretKeySpec keySpec, Cipher cipher) throws Exception{
// 암호화
cipher.init(Cipher.ENCRYPT_MODE, keySpec); // 암호화 모드로 지정
byte[] encrypted = cipher.doFinal(data.getBytes());
return encrypted;
}
public static byte[] Decrypt(byte[] encrypted_data, SecretKeySpec keySpec, Cipher cipher) throws Exception{
//복호화
cipher.init(Cipher.DECRYPT_MODE, keySpec); // 복호화 모드로 지정
byte[] decrypted = cipher.doFinal(encrypted_data);
return decrypted;
}
}