Files
owraweb/src/main/java/com/owrawww/util/AesUtil.java

79 lines
3.0 KiB
Java

package com.owrawww.util;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
/**
* AES-256-GCM 암호화/복호화 유틸리티
* - IV(12 bytes) + 암호문을 Base64로 인코딩하여 저장
*/
@Component
public class AesUtil {
private static final String ALGORITHM = "AES/GCM/NoPadding";
private static final int IV_LENGTH = 12; // GCM 권장 IV 크기
private static final int TAG_BIT_LEN = 128; // GCM 인증 태그 크기
private final SecretKey secretKey;
public AesUtil(@Value("${app.encryption.key}") String base64Key) {
byte[] keyBytes = Base64.getDecoder().decode(base64Key);
if (keyBytes.length != 32) {
throw new IllegalArgumentException("암호화 키는 Base64 인코딩된 32바이트(256bit)여야 합니다.");
}
this.secretKey = new SecretKeySpec(keyBytes, "AES");
}
/**
* 평문 → AES-256-GCM 암호화 → Base64 문자열
*/
public String encrypt(String plainText) {
if (plainText == null || plainText.isEmpty()) return plainText;
try {
byte[] iv = new byte[IV_LENGTH];
new SecureRandom().nextBytes(iv);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(TAG_BIT_LEN, iv));
byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
// IV + 암호문 결합 후 Base64 인코딩
byte[] combined = new byte[IV_LENGTH + encrypted.length];
System.arraycopy(iv, 0, combined, 0, IV_LENGTH);
System.arraycopy(encrypted, 0, combined, IV_LENGTH, encrypted.length);
return Base64.getEncoder().encodeToString(combined);
} catch (Exception e) {
throw new RuntimeException("암호화 실패", e);
}
}
/**
* Base64 암호문 → AES-256-GCM 복호화 → 평문
*/
public String decrypt(String encryptedText) {
if (encryptedText == null || encryptedText.isEmpty()) return encryptedText;
try {
byte[] combined = Base64.getDecoder().decode(encryptedText);
byte[] iv = new byte[IV_LENGTH];
byte[] cipherText = new byte[combined.length - IV_LENGTH];
System.arraycopy(combined, 0, iv, 0, IV_LENGTH);
System.arraycopy(combined, IV_LENGTH, cipherText, 0, cipherText.length);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(TAG_BIT_LEN, iv));
return new String(cipher.doFinal(cipherText), "UTF-8");
} catch (Exception e) {
throw new RuntimeException("복호화 실패", e);
}
}
}