// jsp와 java사이 구간 암호화에 사용
com.shinhanpg.admin.manager.common.util;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
public class AESCryptUtil {
private String encKey;
public AESCryptUtil(String encKey) {
this.encKey = encKey;
}
public String decAES(String enStr) throws Exception {
final int keysize = 256;
final int ivSize = 128;
// 텍스트를 BASE64로 디코드
byte[] ctBytes = Base64.decodeBase64(enStr.getBytes("UTF-8"));
// salt를 구한다.
byte[] saltBytes = Arrays.copyOfRange(ctBytes, 8, 16);
// 암호화된 텍스트를 구한다.
byte[] ciphertextBytes = Arrays.copyOfRange(ctBytes, 16, ctBytes.length);
// 비밀번호와 salt에서 키와 IV값을 가져온다.
byte[] key = new byte[keysize / 8];
byte[] iv = new byte[ivSize / 8];
EvpKDF(encKey.getBytes("UTF-8"), keysize, ivSize, saltBytes, key, iv);
// 복호화
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));
byte[] recoveredPlaintextBytes = cipher.doFinal(ciphertextBytes);
return new String(recoveredPlaintextBytes);
}
private final static byte[] EvpKDF(byte[] password, int keySize, int ivSize, byte[] salt, byte[] resultKey, byte[] resultIv) throws NoSuchAlgorithmException {
return EvpKDF(password, keySize, ivSize, salt, 1, "MD5", resultKey, resultIv);
}
private final static byte[] EvpKDF(byte[] password, int keySize, int ivSize, byte[] salt, int interations, String hashAlgorithm
, byte[] resultKey, byte[] resultIv) throws NoSuchAlgorithmException {
keySize = keySize / 32;
ivSize = ivSize / 32;
int targetKeySize = keySize + ivSize;
byte[] derivedBytes = new byte[targetKeySize * 4];
int numberOfDerivedWords = 0;
byte[] block = null;
MessageDigest hasher = MessageDigest.getInstance(hashAlgorithm);
while (numberOfDerivedWords < targetKeySize) {
if (block != null) {
hasher.update(block);
}
hasher.update(password);
// Salting
block = hasher.digest(salt);
hasher.reset();
// Iterations : 키 스트레칭(key stretching)
for(int i=1; i< interations; i++) {
block = hasher.digest(block);
hasher.reset();
}
System.arraycopy(block, 0, derivedBytes, numberOfDerivedWords*4, Math.min(block.length, (targetKeySize - numberOfDerivedWords)*4));
numberOfDerivedWords += block.length / 4;
}
System.arraycopy(derivedBytes, 0, resultKey, 0, keySize*4);
System.arraycopy(derivedBytes, keySize*4, resultIv, 0, ivSize*4);
return derivedBytes; // key + iv
}
}