DB에 저장된 민감 정보를 암호화할 때, 가장 단순한 방법은 하나의 키로 모든 데이터를 직접 암호화하는 것이다. 그런데 이 키가 유출되면 전체 데이터가 노출된다. 키를 교체하려면 모든 데이터를 다시 암호화해야 한다.
봉투 암호화는 이 문제를 “키를 암호화하는 키"와 “데이터를 암호화하는 키"를 분리하는 구조로 해결한다.
대칭키 암호화
DB 컬럼 암호화처럼 쓰기마다 암호화, 읽기마다 복호화가 필요한 경우에는 대칭키 방식이 적합하다. 하나의 키로 암호화와 복호화를 모두 처리하므로 연산 비용이 낮다.
비대칭키 방식은 공개키/비밀키 쌍을 사용한다. 키 교환이나 전자서명에는 유용하지만, 대칭키 대비 연산 비용이 높고 키 쌍 관리가 복잡하다. 빈번한 암/복호화가 필요한 DB 컬럼 암호화에는 과하다.
AES-256-GCM
대칭키 알고리즘 중에서 AES-256-GCM이 자주 선택되는 이유는 보안, 무결성, 성능을 함께 충족하기 때문이다.
먼저 키 길이를 보면, AES-256은 256비트 키로 무차별 대입 공격에 대한 충분한 내성을 확보한다. 현재 가장 널리 검증된 대칭키 알고리즘이기도 하다.
운용 모드인 GCM(Galois/Counter Mode)은 다른 모드, 예를 들어 CBC와 비교했을 때 두 가지 장점을 갖는다.
첫째, 무결성 보장이다. GCM은 암호화와 동시에 인증 태그를 생성한다. 복호화 시점에 암호문이 변조되었는지 감지할 수 있다. CBC 모드에서는 이를 위해 별도의 HMAC 처리가 필요한데, GCM은 하나의 연산으로 해결한다.
둘째, IV(초기화 벡터)를 사용해 같은 평문이라도 매번 다른 암호문을 생성한다. IV는 암호문과 함께 저장되며, 복호화 시 동일한 IV를 사용해야 원본을 복원할 수 있다.
다만 GCM에는 한 가지 함정이 있다. 같은 키와 같은 IV로 두 번 암호화하면 보안이 완전히 무너진다. IV는 매 암호화마다 유일해야 하며, 보통 안전한 난수 생성기로 만들거나 카운터 기반으로 관리한다.
CMK/DEK 2중 키 구조
봉투 암호화의 핵심은 키를 두 계층으로 나누는 것이다.
flowchart LR
CMK["CMK
(마스터 키)"] -->|"DEK 암호화/복호화"| DEK["DEK
(데이터 암호화 키)"]
DEK -->|"데이터 암호화/복호화"| DATA["평문 데이터"]
최상위에 있는 CMK(Customer Master Key)는 DEK를 암호화하는 용도로만 쓰이고, 데이터에는 직접 닿지 않는다. 일반적으로 HSM(하드웨어 보안 모듈) 안에 보관되어 외부로 추출할 수 없다.
실제 데이터는 그 아래 계층인 DEK(Data Encryption Key)가 담당한다. 평문 DEK로 데이터를 암호화한 뒤, CMK로 DEK 자체를 다시 암호화해 저장한다.
암호화 흐름
DEK는 처음 한 번 키 관리 서비스에서 발급받는다. 이때 평문 DEK와 암호화된 DEK를 동시에 받아, 평문 DEK로는 데이터를 즉시 암호화하고 암호화된 DEK는 데이터와 함께 DB에 저장한다.
sequenceDiagram
participant App as 서비스
participant KMS as 키 관리 서비스
participant DB as DB
App->>KMS: 새 DEK 발급 요청 (CMK 지정)
KMS-->>App: 평문 DEK + 암호화된 DEK 반환
App->>App: 평문 DEK + IV로 데이터 암호화
App->>DB: 암호문 + IV + 암호화된 DEK 저장
Note over App: 평문 DEK 즉시 폐기
읽을 때는 DB에서 암호문, IV, 암호화된 DEK를 가져온 뒤, 키 관리 서비스에 암호화된 DEK의 복호화를 요청한다. 반환된 평문 DEK와 IV로 암호문을 복호화한다. 평문 DEK는 메모리에서만 잠시 사용하고 즉시 폐기한다.
단일 키 방식과의 비교
단일 키 방식에서는 마스터 키가 유출되면 모든 데이터가 위험에 노출된다. 봉투 암호화에서는 DEK가 유출되어도 해당 DEK로 암호화된 데이터만 영향을 받는다. CMK는 HSM 안에 있으므로 유출 가능성 자체가 낮다.
키 회전
봉투 암호화의 실질적 장점은 키 회전에서 드러난다.
단일 키 방식에서 키를 교체하려면 모든 데이터를 새 키로 다시 암호화해야 한다. 데이터 양이 많으면 시간과 비용이 크게 늘어난다.
봉투 암호화에서는 CMK를 교체할 때 DEK만 다시 암호화하면 된다. 데이터 자체는 여전히 같은 DEK로 암호화되어 있으므로 다시 암호화할 필요가 없다. DEK의 크기는 데이터 대비 극히 작으므로 키 회전 비용이 낮다.
flowchart LR
subgraph Before ["키 회전 전"]
CMK1["CMK v1"] --> DEK_ENC1["암호화된 DEK"]
end
subgraph After ["키 회전 후"]
CMK2["CMK v2"] --> DEK_ENC2["암호화된 DEK
(재암호화)"]
end
DEK_ENC1 -.->|"DEK 재암호화만 수행
데이터는 그대로"| DEK_ENC2
내부자 위협에 대응하려면 정기적인 키 회전이 필수적이다. 봉투 암호화는 이 비용을 최소화한다.
클라우드 키 관리 서비스 활용
봉투 암호화를 직접 구현할 수도 있지만, 클라우드 키 관리 서비스를 활용하는 것이 일반적이다. 서비스 선정 시 고려할 기준은 다음과 같다.
- HSM 기반 키 보관: CMK가 소프트웨어가 아닌 하드웨어 안에서만 존재하는지. HSM 기반이면 키 추출 자체가 불가능하다.
- 자동 키 회전: CMK 회전을 자동으로 지원하는지. 수동 회전은 운영 부담이 크다.
- 컨테이너 환경 호환: K8S 같은 컨테이너 환경에서 API 호출 없이 키를 주입할 수 있는지. 서비스 코드의 복잡도에 영향을 준다.
키 발급을 담당하는 서비스와 암호화된 키를 저장하는 서비스를 분리하는 구성도 자주 사용된다. 단일 서비스의 침해가 전체 키에 영향을 주는 경로를 줄일 수 있고, 권한 범위를 좁히는 보안 원칙(least privilege)에도 부합한다.
봉투 암호화가 적합한 경우
봉투 암호화는 다음 조건에서 효과적이다.
- 암호화 대상 데이터가 대량이고 키 회전이 정기적으로 필요한 경우
- 여러 서비스가 같은 암호화 키를 공유해야 하는 경우
- 컴플라이언스 요구로 키 관리 감사 추적이 필요한 경우
반면 소규모 데이터를 일회성으로 암호화하는 경우에는 단일 키 방식으로도 충분하다. 봉투 암호화는 키 관리 복잡도를 추가하는 만큼, 그 복잡도를 정당화할 규모와 요구가 있을 때 선택하는 것이 맞다.
참고
- 무중단 데이터 전환 패턴 — 컬럼 암호화 전환처럼 데이터 형식을 무중단으로 바꾸는 패턴을 다룬다.