데이터 보호를 위한 어노테이션 기반 필드 암호화 처리 방안을 제시합니다. AOP를 활용한 구현 구조는 다음과 같습니다.
의존성 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
도메인 객체 구성
public class SecureData {
@Decrypt
private String securedContent;
private List<SecureItem> items;
}
public class SecureItem {
@Decrypt
private String protectedText;
@Encrypt
private String sensitiveData;
}
암호화 어노테이션 정의
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Encrypt {}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Decrypt {}
암호화 핵심 처리기
public class CryptoProcessor {
private CryptoAdapter cryptoAdapter = new Base64Adapter();
private static final List<Class<?>> IGNORE_TYPES = Arrays.asList(Date.class, Number.class);
public void process(Object target, boolean isDecrypt) {
if (target == null) return;
if (target instanceof List) {
processCollection((List<?>) target, isDecrypt);
} else {
processObject(target, isDecrypt);
}
}
private void processObject(Object obj, boolean isDecrypt) throws Exception {
for (Field field : obj.getClass().getDeclaredFields()) {
field.setAccessible(true);
Object value = field.get(obj);
if (value instanceof String && field.isAnnotationPresent(Encrypt.class)) {
if (!isDecrypt) field.set(obj, cryptoAdapter.encrypt((String) value));
}
// 복호화 로직 생략
}
}
}
암호화 알고리즘 인터페이스
public interface CryptoAdapter {
String encrypt(String plainText);
String decrypt(String cipherText);
}
public class AESAdapter implements CryptoAdapter {
private SecretKeySpec secretKey;
public String encrypt(String text) {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return Base64.getEncoder().encodeToString(cipher.doFinal(text.getBytes()));
}
// 복호화 구현 생략
}
AOP 통합 처리
@Aspect
@Component
public class CryptoAspect {
@Around("execution(* com.example..controller.*.*(..))")
public Object handleCrypto(ProceedingJoinPoint pjp) throws Throwable {
Object[] args = pjp.getArgs();
new CryptoProcessor().process(args, true);
Object result = pjp.proceed();
new CryptoProcessor().process(result, false);
return result;
}
}
컨트롤러 테스트
@RestController
public class DemoController {
@PostMapping("/secure")
public SecureData process(@RequestBody SecureData data) {
return data;
}
}
입력값 전달 시 @Encrypt/@Decrypt 어노테이션이 적용된 필드는 자동으로 암복호화 처리됩니다.