본문 바로가기
system_fundamentals/security_cryptography

DB 컬럼 암호화 방식

by 죄니안죄니 2026. 5. 14.
반응형

DB 컬럼 암호화는 “무엇을 막고 싶은지”에 따라 방식이 달라진다.

실무 기준으로 조회 가능성, 성능, 키 관리까지 같이 묶어서 정리해보자.

 

 
Application Level EncryptionApplication Level EncryptionApplication Level Encryption
 
 

DB 컬럼 암호화는 실무에서 보통:

특정 민감 컬럼만 AES로 암호화해서 저장
 

하는 구조를 말한다.

예:

  • 주민번호
  • 계좌번호
  • 전화번호
  • 이메일
  • 카드번호

같은 것들.


가장 기본 구조

보통 흐름은 이렇다.

애플리케이션
↓
AES 암호화
↓
DB 저장
 

조회할 때는:

DB 조회
↓
AES 복호화
↓
화면 표시
 

핵심은 "DB가 원문을 모르게"

즉 DB 내부에는:

홍길동
01012345678
 

가 아니라:

X82JK...
AB91Q...
 

같은 암호문 저장.


실무에서 제일 많이 쓰는 방식

애플리케이션 레벨 암호화

가장 흔하다.

구조:

Java/Spring
↓ AES-GCM
암호화
↓
Oracle/MySQL/Postgres 저장
 

예시

 
String encrypted = aes.encrypt(phoneNumber);
 

DB에는:

9AFA82B1...
 

저장된다.


왜 AES를 쓰나?

컬럼 데이터는:

  • 복호화 필요
  • 조회 필요
  • 빠른 속도 필요

하기 때문이다.

그래서 대부분:

  • Advanced Encryption Standard
  • AES-GCM
  • AES-CBC(구식)

사용.

현재는 거의 AES-GCM 권장이다. 암호화와 무결성 검증을 같이 처리할 수 있기 때문이다.


구조적으로 보면

원문 데이터
↓
AES 암호화
↓
IV/Nonce 생성
↓
암호문 + Tag 저장
 

실제 DB 저장 형태

예:

컬럼 저장값
phone_enc Base64 암호문
nonce IV( 랜덤값 )/nonce 
tag 인증태그

혹은:

[nonce][ciphertext][tag]
 

합쳐서 저장하기도 한다.


중요한 문제 — 검색이 어려움

암호화하면:

WHERE phone = ?
 

같은 검색이 안 된다.

왜냐면 같은 값도 nonce 때문에:

매번 다른 암호문
 

되기 때문이다.


그래서 실무에서 많이 쓰는 구조

분리구조 : 1.암호화 컬럼 (복호화용) + 2.해시 컬럼 (검색용) 

예:

컬럼 역할
phone_enc 복호화용 AES
phone_hash 검색용 SHA-256

예시

01012345678
↓
AES → 복호화 가능 저장
↓
SHA-256 → 검색용 저장
 

조회할 때 

WHERE phone_hash = SHA256('01012345678' + pepper)

즉, 표시는 복호화, 검색은 해시로 처리.

 


로그인 비밀번호와 차이

엄청 중요하다.


비밀번호

복호화 절대 안 함
 

→ bcrypt/Argon2 해시값 저장


컬럼 암호화

나중에 다시 보여줘야 함
 

→ AES 암호화 저장


예를 들어

주민번호

고객센터에서 다시 봐야 함.

→ AES 필요.


비밀번호

운영자도 보면 안 됨.

→ 해시만 저장.


키 관리가 핵심

사실 컬럼 암호화에서 제일 중요한 건 암호화 알고리즘보다 키 관리이다:

AES 키를 어디 보관하느냐
 

다.


위험한 구조

# 소스코드에 하드코딩
private static final String KEY = "1234567890123456";
 

실무에서 매우 위험.


보통 실무에서는 외부 키 관리

방법 1

환경변수.

ENV KEY
 

방법 2

KMS 사용.

예:

  • Amazon Web Services KMS
  • Google Cloud KMS
  • Microsoft Key Vault
애플리케이션
↓
KMS에게 요청
"DEK 복호화 해줘"
↓
KMS 내부에서만 CMK 사용
↓
복호화된 DEK 반환
↓
앱이 AES 암호화 수행
 

즉:

앱이 CMK 원문을 직접 들고있지 않음

그림으로 이해

전화번호
↓ DEK로 암호화
암호문

DEK
↓ CMK로 암호화
Encrypted DEK
 

왜 2단계 키 구조를 쓰냐

핵심은:

키 교체(rotation)
 

때문.


나쁜 구조

데이터를 AES키 하나로만 암호화
 

문제:

키 바꾸려면:

DB 전체 재암호화
 

해야 함.

대규모 서비스면 사실상 지옥.


좋은 구조

데이터는 DEK로 암호화
DEK만 CMK로 감쌈
 

CMK 교체 시:

DEK만 다시 암호화
 

하면 끝.

엄청 효율적.

 

 

(NIST도 암호화 키의 생성, 보관, 교체, 폐기 같은 키 수명주기 관리가 중요하다고 설명함)



정리

비밀번호        → Argon2 / bcrypt 해시
개인정보 표시용 → AES-256-GCM 암호화
검색/중복체크   → SHA-256/HMAC 해시 컬럼 별도 저장
암호화 키       → 소스코드/DB에 두지 말고 KMS/Vault/환경변수 관리
 

가장 현실적인 기본 구조는:

원문 → 애플리케이션에서 AES-GCM 암호화 → DB 저장
원문 → HMAC-SHA256 → 검색용 컬럼 저장

 

컬럼
phone_enc AES(01012345678)
phone_hash HMAC_SHA256(01012345678)

 조회 시

01012345678를 검색하면 

애플리케이션 서버에서 HMAC_SHA256(01012345678) = > A1B2C3D4... 해시값이 전달됨 (로그에도 해시값만 노출. 앱 메모리에는 입력값으로 존재할 순 있으나 일반적이로 남지는 않으니까 패스)

SELECT *
FROM USER
WHERE phone_hash = 'A1B2C3D4...'

 있는 row의 phone_enc를 앱서버에서 AES복호화 


컬럼 암호화 (AES) vs TDE

많이 헷갈린다.


TDE(Transparent Data Encryption)

예:

  • Oracle TDE
  • MSSQL TDE

특징

DB 파일 자체 암호화
 

즉:

  • 디스크 탈취 방어
  • DBA는 평문 조회 가능, SQL Injection, 내부 계정 탈취에는 약함

컬럼 암호화(AES)

특정 컬럼만 애플리케이션 레벨 암호화
 

즉 DBA도 원문 못 보게 가능. SELECT 해도 암호문만 보임


비교

공격 TDE컬럼  AES(컬럼암호화)
디스크 탈취 강함 강함
백업 유출 강함 강함
DBA 평문조회 약함 강함
SQL Injection 약함 강함
앱 서버 탈취 약함 약함

 

실무에서 자주 쓰는 패턴

실무 보안 수준
= 민감 컬럼 암호화(AES)
+ 검색용 해시(HMAC/SHA) 컬럼 추가
+ TDE
를 같이 쓰는 경우가 많음

 

전화번호

AES 저장
SHA-256 검색
 

카드번호

보통:

  • 일부 마스킹 저장
  • 일부만 복호화 가능

주민번호

강한 AES + 접근통제.


Java 실무 스타일

보통:

  • JCE(Java Cryptography Extension)
  • Spring AOP
  • MyBatis TypeHandler
  • JPA Converter

등으로 자동 암복호화 구현한다.


특히 많이 쓰는 구조

MyBatis:

조회 시 자동 복호화
저장 시 자동 암호화
 

TypeHandler 구조 많이 쓴다.


핵심 요약

DB 컬럼 암호화는 보통:

민감 컬럼을 AES로 암호화 저장하고,
필요 시 애플리케이션에서 복호화하는 방식
 

이며,

실무 핵심은:

암호 알고리즘보다
"키 관리"와 "검색 구조 설계"
 

다.

 

반응형

'system_fundamentals > security_cryptography' 카테고리의 다른 글

RSA 원리  (0) 2026.05.14
공개키 암호화는 어떻게 가능한가  (0) 2026.05.14
용어정리  (0) 2026.05.14
파일 암호화 구조  (0) 2026.05.14
스트림 암호 vs 블록 암호  (0) 2026.05.14

댓글