공공부하자개발 · 영어 학습 노트
자바
실무 확장Excel · 파일 업로드 · DB 연동0/22 완료
  • 01Excel(XLSX) 구조와 순수 JDK로 읽기/쓰기
  • 02Apache POI로 Excel 업로드/다운로드
  • 03파일 업로드/다운로드 서버 (HttpServer)
  • 04JDBC 기초와 트랜잭션 (H2)
  • 05MyBatis 어노테이션 매퍼로 쿼리 연동
  • 06MyBatis XML 매퍼 · Oracle 방언 · PageHelper · Spring Boot
  • 07REST API 서버와 JSON
  • 08Vue 3 SPA 와 Java 서버 연동
  • 09@Scheduled 운영
  • 10로깅 실무: 레벨·계층, MDC 추적, 예외·성능, 마스킹, 롤링, JSON 로그
  • 11외부 API 연동
  • 12테스트 실무
  • 13암호화·개인정보 보호
  • 14인코딩·한글 실무
  • 15@Transactional 심화
  • 16긴 작업 비동기 처리와 진행률
  • 17SFTP·FTP 파일 연계
  • 18로컬 캐시와 @Cacheable
  • 19메일·알림 발송
  • 20웹 보안 체크리스트
  • 21빌드 도구와 폐쇄망 의존성 반입
  • 22성능 측정: p50·p95·p99, 측정 계층, JFR, JMH 함정, 자체 부하 테스트, 병목 순위
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › 실무 확장 › 13 / 22

암호화·개인정보 보호

AES-GCM, 키 관리·교체, 검색용 HMAC, 컬럼 암호화, 마스킹
섹션 7진행 0 / 22
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6연습 문제7정리‹ 이전다음 ›

6. 연습 문제

문제 1. `Crypto` 에 AAD(추가 인증 데이터) 를 지원하는 오버로드 추가

encrypt(String plain, String aad) 와 decrypt(String token, String aad) 를 추가하세요. AAD 는 암호화하지 않지만 무결성 검증에 포함됩니다. 힌트: Cipher.updateAAD(byte[]) 를 init 직후, doFinal 이전에 호출합니다.

java
public String encrypt(String plain, String aad) {
    try {
        SecretKey key = keys.get(currentVersion);
        byte[] iv = new byte[IV_LEN];
        RANDOM.nextBytes(iv);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGO);
        cipher.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(TAG_BITS, iv));
        cipher.updateAAD(aad.getBytes("UTF-8"));
        byte[] ct = cipher.doFinal(plain.getBytes("UTF-8"));
        byte[] ivAndCt = new byte[iv.length + ct.length];
        System.arraycopy(iv, 0, ivAndCt, 0, iv.length);
        System.arraycopy(ct, 0, ivAndCt, iv.length, ct.length);
        return currentVersion + ":" + Base64.getEncoder().encodeToString(ivAndCt);
    } catch (Exception e) {
        throw new RuntimeException("암호화 실패", e);
    }
}

decrypt 도 같은 방식으로 updateAAD 를 호출해야 하며, 암호화할 때와 다른 AAD 를 넘기면 AEADBadTagException 이 발생합니다. AAD 는 보통 테이블명·컬럼명처럼 컨텍스트를 고정하는 값으로 씁니다.

문제 2. 검색용 해시에 저장용 접두어(salt) 추가로 레인보우 테이블 대응

searchHash 를 확장해, 값 앞에 애플리케이션 전역 고정 문자열(pepper) 을 붙인 뒤 해시하도록 바꾸세요. 힌트: HMAC 은 이미 키가 있어 pepper 효과가 있지만, 값 자체를 변형하는 방식도 가능합니다.

java
private static final String PEPPER = "app-fixed-context-v1";

public String searchHash(String value) {
    try {
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(hmacKey);
        byte[] out = mac.doFinal((PEPPER + value).getBytes("UTF-8"));
        return Base64.getEncoder().encodeToString(out);
    } catch (Exception e) {
        throw new RuntimeException("해시 실패", e);
    }
}

HMAC 은 키 자체가 비밀이므로 pepper 없이도 안전하지만, 키 유출 시 이중 방어선이 될 수 있습니다. 다만 PEPPER 를 바꾸면 기존에 저장된 모든 해시가 무효화되므로 신중하게 결정합니다.

연습 문제
    이전 섹션5 자주 하는 실수 (Tip)6 / 7다음 섹션7 정리