AWS KMS를 활용한 E2EE(End-to-End Encryption)

Yangchef·2025년 8월 23일
post-thumbnail

개요

프로젝트를 진행하다 보면 절대 외부에 노출되면 안되는 민감한 데이터를 다룰 때가 있다.
이번 프로젝트에서는 사용자의 AWS 계정 정보, 비밀 키 값 등이 포함된 요청 패킷을 안전하게 전송해야 하는 미션이 주어졌고, 고민 끝에 AWS Key Management Service(KMS)를 활용한 End-to-End 암호화(E2EE)를 도입하기로 마음먹었다.


왜 E2EE ?

먼저, 내가 마주한 보안 요구사항은 클라이언트에서 서버로 전송되는 Request 패킷 전체를 보호하는 것이었다. 이 패킷 안에는 제3자에게 노출될 경우 심각한 보안 사고로 이어질 수 있는 정보가 담겨 있었다.

단순히 전송 계층만 암호화하는 HTTPS/TLS만으로는 부족하다고 느꼈다. 중간에 위치한 프록시나 로드 밸런서 등에서 데이터가 평문으로 노출될 가능성을 원천 차단하고 싶었기 때문이다.

그래서 데이터가 생성되는 출발지(클라이언트)부터 최종 목적지(서버)까지, 그 누구도 내용을 엿볼 수 없도록 하는 E2EE가 유일한 해답이라고 생각했다.

이때, 암호화 키를 안전하게 생성하고 관리하는 것이 핵심 과제였고, 나는 자연스럽게 AWS의 관리형 서비스인 AWS KMS로 눈을 돌렸다. KMS는 복잡한 키 관리를 AWS에 위임하고, 나는 애플리케이션 로직에만 집중할 수 있게 해주는 강력한 도구였다.


AWS KMS

AWS Key Management Service (AWS KMS) is an AWS managed service that makes it easy for you to create and control the encryption keys that are used to encrypt your data.

AWS 공식문서에서 확인할 수 있듯이 KMS는 암호화를 위한 key를 생성하고 관리할 수 있는 서비스다.

KMS를 선택한 주요 이유는 다음과 같다.

1. 완전 관리형 서비스
복잡한 키 관리 인프라를 직접 구축하고 운영할 필요 없이, AWS가 제공하는 안전하고 확장 가능한 키 관리 서비스를 활용할 수 있다.

2. 세분화된 접근 제어
IAM과 긴밀하게 통합되어 있어, 키 사용에 대한 매우 세밀한 권한 관리가 가능하다.

3. 감사 및 모니터링
AWS CloudTrail과 연동하여 모든 키 사용에 대한 로깅과 모니터링이 용이하다.

4. 하드웨어 보안 모듈(HSM) 기반
키가 FIPS 140-2 레벨 2 인증된 하드웨어에서 안전하게 생성되고 관리된다.


첫번째 시도

비대칭 키를 활용한 암호화

처음 구상했던 방식은 비대칭 키를 활용하는 것이었다.
클라이언트가 암호화에 사용하는 키는 결국 사용자에게 노출될 수밖에 없으니, 암호화 키와 복호화 키가 달라야 한다는 판단이었다.

  1. AWS KMS에서 비대칭 키(Asymmetric Key) 페어를 생성한다. (예: RSA 2048)
  2. 클라이언트는 KMS에서 다운로드한 공개 키(Public Key)로 요청 데이터를 암호화하여 서버로 전송한다.
  3. 서버 애플리케이션은 수신한 암호화된 데이터를 KMS의 Decrypt API를 호출하여 KMS 내부에 안전하게 보관된 개인 키(Private Key)로 복호화한다.

이 방식의 가장 큰 장점은 개인 키가 절대로 KMS 외부로 노출되지 않는다는 점이었다.
클라이언트는 암호화만 할 수 있을 뿐, 다른 사람의 데이터를 복호화할 수는 없다.
모든 복호화 권한은 KMS와 통신할 수 있는 서버 애플리케이션에만 부여되므로, 보안적으로 매우 이상적인 구조라고 생각했다.

예상치 못한 비대칭 키의 한계

하지만, 예상치 못한 문제 상황을 마주하게 되었다.
바로 비대칭 키 암호화에는 암호화할 수 있는 평문의 길이에 제한이 있다는 사실이었다.

AWS KMS FAQ에 따르면, 비대칭 키를 사용한 직접 암호화 작업은 최대 4KB의 데이터만 처리할 수 있었다.
내가 사용하려던 RSA 3072 알고리즘의 경우, 패딩 방식을 고려하면 실제 암호화 가능한 데이터는 약 350 byte에 불과했다.

현재 프로젝트에서는 사용자가 작성한 Terraform 코드를 요청에 담아 보낼 수도 있었는데, 이 코드의 길이는 수십 KB를 훌쩍 넘길 수 있었다.


두번째 시도

봉투 암호화 (Envelope encryption)

길이 제한 문제를 해결하기 위해 조사하던 중, 봉투 암호화(Envelope Encryption)를 알게되었다. 이는 하이브리드 암호화라고도 불리며, 비대칭 키 암호화의 강력한 키 관리 능력과 대칭 키 암호화의 빠른 처리 속도 및 길이 제약 없는 장점을 결합한 방식이었다.

봉투 암호화의 핵심 아이디어는 데이터는 대칭키로 암호화하고, 이 대칭키를 비대칭키로 암호화하는 것이다.

Client Side

Server Side

  1. [클라이언트] KMS의 GenerateDataKey API를 호출하여 마스터 키로부터 데이터 키 생성을 요청한다.
  2. [KMS 응답] KMS는 권한 확인 후, 암호화에 사용할 평문 데이터 키(Plaintext Data Key)마스터 키로 암호화된 암호화된 데이터 키(CiphertextBlob)를 클라이언트에게 반환한다.
  3. [클라이언트] 전달받은 평문 데이터 키를 사용하여 원본 메시지를 암호화한다. (이때는 길이 제한이 없는 AES와 같은 대칭키 알고리즘 사용)
  4. [클라이언트] 암호화 후 즉시 메모리에서 평문 데이터 키를 삭제하고, 암호화된 메시지와 암호화된 데이터 키를 함께 서버로 전송한다.
  5. [서버] 두 데이터를 수신한다.
  6. [서버] KMS의 Decrypt API를 호출하면서, 함께 받은 암호화된 데이터 키를 전달한다.
  7. [KMS 응답] KMS는 호출 주체의 권한을 확인하고, 내부의 마스터 키를 사용해 암호화된 데이터 키를 복호화하여, 그 결과인 평문 데이터 키를 서버에게 반환한다.
  8. [서버] 전달받은 평문 데이터 키를 사용하여 암호화된 메시지를 복호화한다.
  9. [서버] 복호화가 끝나면 즉시 메모리에서 평문 데이터 키를 삭제한다.

성능과 비용에 대한 고민

레이턴시 Trade-Off

KMS API를 활용한 E2EE 구현은 성능적 측면에서 trade-off가 존재한다.
모든 요청마다 GenerateDataKeyDecrypt API를 호출해야 하므로, 각 요청의 레이턴시가 약간 증가할 수밖에 없다.

실제 벤치마크 결과, 각 API 호출로 인해 요청당 약 50-100ms의 추가 지연 시간이 발생했다. 대부분의 일반적인 서비스에서는 큰 문제가 되지 않지만, 고성능을 요구하는 시스템의 경우 신중한 고려가 필요하다.

비용 최적화 전략

KMS는 API 호출 횟수에 따라 비용이 발생한다. 요청량이 매우 많은 서비스의 경우, 비용 최적화를 위한 전략이 필요하다.

데이터 키 캐싱은 하나의 해결책이 될 수 있다. 동일한 데이터 키를 일정 시간(예: 5-10분) 동안 재사용함으로써 API 호출 횟수를 줄일 수 있다. 하지만 이는 양날의 검과 같다.

장점
API 호출 비용 절감, 레이턴시 감소

단점
키 순환 주기가 길어져 잠재적인 보안 리스크 증가

결국 보안과 성능, 비용 사이의 미묘한 균형을 찾는 것이 중요하다.
서비스의 특성과 보안 요구사항을 종합적으로 고려하여 최적의 전략을 선택해야 한다.


KMS 기반 E2EE를 도입하며 고려했던 사항

IAM 정책을 통한 최소 권한 부여
KMS 키 정책과 IAM 정책을 설정하며, 키를 사용하는 주체에게 꼭 필요한 권한(kms:GenerateDataKey, kms:Decrypt)만 부여해야 한다.

암호화 컨텍스트(Encryption Context) 활용
KMS API 호출 시 암호화 컨텍스트를 추가하면 보안을 한층 더 강화할 수 있다. 이는 암호화된 데이터에 대한 추가적인 인증 데이터(AAD) 역할을 하여, 특정 컨텍스트에서만 데이터가 복호화되도록 강제할 수 있다.
예를 들어, {"userId": "user-123"}와 같은 컨텍스트를 포함하여 암호화했다면, 복호화 시에도 동일한 컨텍스트를 제공해야만 성공한다. 이는 데이터의 무결성을 보장하고 감사 추적에도 유용하다.

오류 처리 및 재시도 로직
KMS API 호출은 네트워크 문제나 Throttling 등으로 인해 일시적으로 실패할 수 있다. AWS SDK에 내장된 재시도(Retry) 및 지수 백오프(Exponential Backoff) 로직을 적절히 활용하여 안정성을 높이는 것이 중요하다.


Reference

AWS - AWS KMS keys
Google Cloud - Envelope encryption

0개의 댓글