태그
#SPRING
#암호화
#복호화
#SPRINGBOOT
Spring 암호화/복호화 하기
2023년 11월 30일 15:23

🔒 암호화
@Slf4j
@Component
public class KeyEncrypt {
private final static String shaAlg = "SHA-256";
private final static String aesAlg = "AES/CBC/PKCS5Padding";
private final static String key = "MyTestCode-32Character-TestAPIKey";
private final static String iv = key.subString(0, 16);
public String encrypt(String text) {
try {
String shaKey = getShaKey(text);
return getAesKey(shaKey);
} catch (Exception e) {
throw new RuntimeException("암호화 처리중에 에러가 발생했습니다. e = {}", e.getMessage());
}
}
// SHA-256 키 만들기
private String getShaKey(String text) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance(shaAlg);
md.update(text.getBytes());
return bytesToHex(md.digest());
}
// AES 키 만들기
private String getAesKey(String text) throws Exception {
Cipher cipher = Cipher.getInstance(aesAlg);
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec);
byte[] encodedBytes = cipher.doFinal(text.getBytes());
byte[] encrypted = Base64.getEncoder().encode(encodedBytes);
return new String(encrypted).trim();
}
private String bytesToHex(byte[] bytes) {
StringBuilder builder = new StringBuilder();
for (byte b : bytes) {
builder.append(String.format("%02x", b));
}
return builder.toString();
}
}
- 주의할 점
- SHA-256
- 바이트를 이진수로 변환해야 합니다
- AES
- key는 16, 24, 32 바이트(영문 32자), iv는 16 바이트 이어야합니다
- SHA-256
🔑 복호화
❗️ SHA 알고리즘은 해싱을 통해 암호화를 하기 때문에 복호화가 불가능 합니다
@Component
public class KeyDecrypt {
private final static String alg = "AES/CBC/PKCS5Padding";
private final static String key = "MyTestCode-32Character-TestAPIKey";
private final static String iv = key.subString(0, 16);
public String decrypt(String clientKey) {
try {
Cipher cipher = Cipher.getInstance(alg);
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);
byte[] decoedBytes = Base64.getDecoder().decode(clientKey.getBytes());
byte[] decrypted = cipher.doFinal(decoedBytes);
return new String(decrypted).trim();
} catch (Exception e) {
throw new RuntimeException("복호화 처리중에 에러가 발생했습니다. e = {}", e.getMessage());
}
}
}
TMI 😂
- 개발중 만났던 exception들
- IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
- Base64로 디코딩을 하지 않고, AES 알고리즘으로 복호화 했을 때 나타난 인셉션입니다
- 복호화를 해야하는데 Chiper 모드를 암호화로 설정하고 디코딩을 했을 때에도 나타났습니다
- InvalidKeyException: Parameters missing
- iv를 사용하지 않고, AES로 암/복호화를 시도했을 때 나타난 에러입니다 AES 알고리즘을 암호화할때는 iv를 지정해주지 않으면, 자동적으로 랜덤 iv를 만들어서 사용해버리기 때문에 복호화가 불가능한 상태가 됩니다 따라서 AES 암호화를 할 때는 꼭 iv를 설정해야합니다!
- IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
👉🏻 docs