CertNote/ 출퇴근 학습 노트
로드맵
KOEN
CLF-C02 · FoundationalCloud Practitioner - Foundational
DVA-C02 · AssociateDeveloper - Associate
  • Week 1
    • 1.개발자 시점에서 본 AWS: 리전, 인프라, 그리고 책임의 경계
    • 2.IAM의 4대 엔터티: User, Group, Role, Policy
    • 3.STS와 정책 조건: 임시 자격증명의 깊은 세계
    • 4.AWS CLI와 SDK: 자격증명 체이닝부터 SigV4까지
    • 5.Week 1 종합: 인프라와 IAM이 만드는 신뢰의 사슬
  • Week 2
  • Week 3
  • Week 4
  • Week 5
  • Week 6
  • Week 7
  • Week 8
  • Week 9
    • 1.KMS: 암호화 키를 직접 만지지 않고 다루는 기술
    • 2.Secrets Manager와 Parameter Store: 비밀을 코드 밖으로 꺼내기
    • 3.Cognito: 인증과 인가를 두 개의 풀로 나눈 이유
    • 4.WAF, Shield, ACM: 트래픽이 앱에 닿기 전에 거르는 세 겹
    • 5.Week 9 복습: 보안은 한 줄의 설정이 아니라 계층의 합이다
  • Week 10
  • Week 11
  • Week 12
  • Week 13
SAA-C03 · AssociateSolutions Architect - Associate
SOA-C02 · AssociateCloudOps Engineer - Associate
SAP-C02 · ProfessionalSolutions Architect - Professional
DOP-C02 · ProfessionalDevOps Engineer - Professional
SCS-C03 · SpecialtySecurity - Specialty
MLA-C01 · AssociateMachine Learning Engineer - Associate
AIF-C01 · FoundationalAI Practitioner - Foundational
DEA-C01 · AssociateData Engineer - Associate
MLS-C01 · SpecialtyMachine Learning - Specialty
합격 후기

© CertNote · 주간랩스

  • 소개
  • 수정 기록
  • 문의
  • 이용약관
  • 개인정보처리방침
← DVA-C02/Week 9/Day 1

기준: DVA-C02 시험 가이드·오류 제보

DVA-C02· AssociateWeek 9 · Day 1읽기 약 17분

Day 1 - KMS: 암호화 키를 직접 만지지 않고 다루는 기술

암호화를 처음 배우는 개발자가 가장 먼저 부딪히는 벽은 알고리즘이 아니라 키를 어디에 둘 것인가라는 질문이다. AES-256으로 데이터를 암호화하는 코드는 한 줄이면 되지만, 그 256비트 키를 어디 저장할지 정하는 순간 모든 게 복잡해진다. 키를 코드에 박으면 git에 영원히 남고, 환경변수에 두면 프로세스 덤프로 새고, 파일에 두면 그 파일을 또 누가 지키느냐는 무한 후퇴가 시작된다. "암호화의 진짜 문제는 암호화가 아니라 키 관리"라는 보안 업계의 오래된 격언은 정확히 이 지점을 가리킨다. AWS KMS(Key Management Service)는 바로 그 키 관리 문제를 "키를 절대 평문으로 밖에 내보내지 않는다"는 단 하나의 설계 원칙으로 풀어낸 서비스다.

DVA-C02 시험에서 KMS는 단독 주제로도 나오지만, 그보다 S3·EBS·RDS·DynamoDB·Secrets Manager 등 거의 모든 저장 서비스의 암호화 뒤에 KMS가 있기 때문에 더 중요하다. KMS의 동작 모델 — 특히 봉투 암호화(Envelope Encryption)와 키 정책의 3중 권한 구조 — 을 이해하면 보안 섹션의 시나리오를 풀 수 있다. 이번 글은 KMS가 왜 키를 밖으로 안 내보내도록 설계됐는지, 4KB 한도가 어디서 나온 숫자인지, 그리고 그 한도를 우회하는 봉투 암호화가 실제로 어떻게 동작하는지를 깊이 들여다본다.

KMS가 풀려고 한 문제: 키는 절대 밖으로 나가면 안 된다

KMS의 핵심 설계 결정은 의외로 단순하다. CMK(Customer Master Key)의 키 재료(key material)는 어떤 API로도 평문으로 추출할 수 없다. kms:Encrypt를 호출하면 KMS가 내부에서 암호화해 ciphertext만 돌려주고, kms:Decrypt를 호출하면 내부에서 복호화해 plaintext만 돌려준다. 키 자체는 HSM(Hardware Security Module) 경계 안에서만 존재하고 그 경계를 넘지 않는다. 이것이 KMS와 "키를 만들어 파일로 다운로드받는" 전통적 PKI 도구의 근본적 차이다.

이 설계는 암호학의 키 격리(key isolation) 원칙을 클라우드 규모로 구현한 것이다. 키를 추출 불가로 만든 것은 편의를 희생한 결과가 아니라, "추출할 수 없는 것은 유출될 수 없다"는 위협 모델의 직접적 귀결이다.

KMS API에는 GetKeyMaterial 같은 함수가 의도적으로 없다. 키를 가져오는 유일한 방향은 반대 방향 — Imported Key Material 기능으로 사용자가 자기 키를 KMS 안으로 넣을 수만 있다. 이때도 KMS의 공개키(GetParametersForImport로 받은 wrapping key)로 키를 암호화해 보내야 하고, 한 번 들어가면 다시 못 꺼낸다. AWS가 키를 못 보는 BYOK(Bring Your Own Key) 시나리오에서도 이 단방향성은 유지된다. 사용자가 외부 HSM에 원본을 보관하고 KMS의 복사본을 언제든 삭제할 수 있다는 게 컴플라이언스 고객에게 중요한 통제권이다.

이 "키가 안 나간다"는 제약이 곧 KMS의 가장 큰 한계로 이어진다. 모든 암호화·복호화가 KMS API 호출을 거쳐야 하므로, 큰 데이터를 직접 KMS로 암호화하면 ① 데이터를 네트워크로 KMS에 보냈다가 ② 다시 받아와야 한다. 그래서 KMS는 직접 암호화 가능한 데이터 크기를 최대 4KB로 제한한다.

⚠️ 함정: "4KB"라는 숫자는 시험에 나온다. kms:Encrypt로 직접 암호화할 수 있는 평문은 최대 4096바이트다. 이걸 모르면 "10MB 파일을 KMS로 암호화하는 법"에서 kms:Encrypt 직접 호출을 고르는 함정에 빠진다. 정답은 봉투 암호화다. 4KB가 한도인 이유는 KMS가 "작은 비밀(데이터 키, 패스워드, 토큰)을 보호하는 도구"이지 "대용량 데이터를 직접 암호화하는 도구"가 아니라는 설계 의도를 반영한다.

봉투 암호화: 키로 키를 암호화하는 두 단계 트릭

4KB 한도를 우회하는 방법은 우아하다. KMS에게 데이터를 직접 암호화해달라고 하지 말고, 일회용 데이터 키(DEK, Data Encryption Key)를 하나 만들어달라고 한 뒤, 그 키로 큰 데이터를 로컬에서 직접 암호화하는 것이다. KMS의 마스터 키(CMK)는 오직 그 데이터 키를 보호(암호화)하는 데만 쓰인다. 키가 키를 감싼다는 의미에서 봉투(envelope) 암호화라 부른다.

import boto3, os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
 
kms = boto3.client('kms')
 
# 1) KMS에 데이터 키 한 개 요청 - 평문 DEK와 암호화된 DEK를 동시에 받는다
resp = kms.generate_data_key(
    KeyId='alias/myapp-key',
    KeySpec='AES_256'
)
plaintext_dek  = resp['Plaintext']        # 32바이트 평문 키 (암호화에 사용)
encrypted_dek  = resp['CiphertextBlob']   # CMK로 암호화된 키 (데이터와 함께 저장)
 
# 2) 평문 DEK로 큰 데이터를 로컬에서 직접 암호화 (KMS 호출 없음)
aesgcm = AESGCM(plaintext_dek)
nonce  = os.urandom(12)
ciphertext = aesgcm.encrypt(nonce, b'...10MB of data...', None)
 
# 3) 평문 DEK를 메모리에서 즉시 폐기 - 이게 핵심
del plaintext_dek
 
# 4) 저장: [암호화된 데이터 + nonce + 암호화된 DEK]
#    암호화된 DEK는 평문으로 풀려면 반드시 KMS Decrypt를 거쳐야 함

복호화는 정확히 거꾸로다. 저장된 암호화된 DEK를 kms:Decrypt로 풀어 평문 DEK를 잠깐 받은 뒤, 그것으로 데이터를 로컬에서 복호화하고, 평문 DEK를 다시 폐기한다.

이 패턴은 KMS만의 발명이 아니라 PGP/GPG가 쓰는 하이브리드 암호화와 같은 계보다. 대칭 암호화는 빠르지만 키 교환이 어렵고, 비대칭 암호화는 키 교환이 쉽지만 느리다. 그래서 "큰 데이터는 대칭, 작은 키는 비대칭(또는 보호된 마스터 키)으로" 처리하는 것이 하이브리드 암호화다. 봉투 암호화는 이 아이디어를 클라우드 키 관리에 옮긴 것이고, S3 SSE-KMS, EBS 볼륨 암호화, RDS 암호화가 전부 내부적으로 이 방식을 쓴다.

GenerateDataKey가 평문 DEK와 암호화된 DEK를 한 번의 호출로 동시에 돌려주는 게 핵심이다. 만약 둘을 따로 받아야 한다면 평문 DEK를 받는 API가 필요한데, 그건 "키를 평문으로 내보낸다"는 KMS의 금기를 깬다. AWS는 이 모순을 "데이터 키는 CMK가 아니다"로 해결했다 — DEK는 CMK가 그 자리에서 생성한 일회용 종속 키이고, 평문 형태로 잠깐 나가도 곧 폐기되므로 CMK 자체의 격리는 깨지지 않는다. 평문 DEK가 절대 디스크에 닿으면 안 되는 이유가 여기 있다. 디스크에 남으면 암호화된 데이터 옆에 평문 키가 같이 저장돼 암호화가 무의미해진다. 그래서 GenerateDataKeyWithoutPlaintext라는 변종도 있는데, 암호화된 DEK만 받아 미리 저장해두고 나중에 복호화 시점에만 평문화하는 용도다.

S3 SSE-KMS에서 객체 수백만 개를 한꺼번에 다루는 워크로드는 객체마다 GenerateDataKey를 호출하면 KMS API 한도에 부딪힌다. AWS가 2020년 도입한 S3 Bucket Key는 이 문제를 봉투 암호화의 한 단계를 더 추가해 해결했다 — 버킷 수준에서 짧은 시간 캐싱되는 버킷 키를 만들어 객체별 DEK 생성 시 KMS 호출을 줄인다(AWS 문서 기준 최대 99%). 봉투 암호화의 "키로 키를 감싼다"는 발상을 한 겹 더 쌓은 셈이고, 대량 객체 환경에서 KMS 비용을 낮출 수 있다.

키 유형: 누가 키를 소유하고 통제하는가

KMS의 키는 "누가 만들고 누가 정책을 통제하느냐"에 따라 세 가지로 나뉜다. 이 구분이 시험 함정의 소재가 된다.

유형비용키 정책 제어자동 회전사용처
AWS Owned Key무료보이지 않음AWS가 관리고객에게 노출 안 되는 내부 암호화
AWS Managed Key (aws/<service>)무료보기만 가능자동 (1년)S3·RDS 등 서비스 기본 암호화
Customer Managed Key (CMK)$1/월 + API완전 제어옵션 (1년)세밀한 권한·감사가 필요한 경우

AWS Managed Key의 자동 회전 주기는 365일(1년) 이다. 2022년 5월 이전 자료에는 "3년(1095일)"로 적혀 있지만 AWS가 정책을 바꿔 이제는 1년이다. "AWS Managed Key 회전 주기"가 나오면 1년을 고른다. CMK의 자동 회전도 기본 1년이며, 2024년부터는 사용자 지정 주기(90~2560일)도 설정할 수 있게 됐다.

키 회전이 "키를 새로 만든다"가 아니라는 점이 중요하다. CMK를 회전하면 새 키 재료(backing key)가 추가되지만, 키의 ARN·키 ID·alias는 그대로다. 새로 암호화하는 데이터는 새 backing key로, 이미 암호화된 데이터는 그것을 만든 옛 backing key로 자동 복호화된다 — KMS가 ciphertext 헤더에 어느 backing key를 썼는지 기록해두기 때문이다. 그래서 회전 후에도 옛 데이터를 다시 암호화할 필요가 없고, 애플리케이션 코드도 ARN만 참조하므로 바뀔 게 없다. 이것이 "회전했는데 옛 데이터를 못 읽는 것 아니냐"는 오해에 대한 답이다.

키 정책 + IAM + Grant: KMS의 3중 권한 모델

KMS 권한이 다른 AWS 서비스와 다른 결정적 지점은 키 정책(Key Policy)이 권한의 최종 권위라는 점이다. 대부분의 서비스는 IAM 정책만으로 접근을 통제하지만, KMS는 키 자체에 붙은 키 정책이 "이 키에 IAM 권한을 위임할지" 여부까지 결정한다.

{
  "Sid": "Enable IAM User Permissions",
  "Effect": "Allow",
  "Principal": { "AWS": "arn:aws:iam::111122223333:root" },
  "Action": "kms:*",
  "Resource": "*"
}

이 statement가 키 정책에 없으면, IAM 정책에서 아무리 kms:Decrypt를 허용해도 효력이 없다. root principal을 허용한다는 건 "이 계정의 IAM 정책에 권한 위임을 인정한다"는 선언이고, 이게 빠지면 키 정책에 명시된 principal만 키를 쓸 수 있다.

⚠️ 함정: "IAM 정책으로 kms:*를 줬는데 왜 접근이 안 되는가?"는 시험에 나오는 시나리오다. 답은 키 정책에 IAM 위임 statement가 없기 때문이다. 기본 키 정책에는 이 statement가 자동으로 들어가지만, 커스텀 키 정책을 작성하면서 빠뜨리면 키를 만든 본인조차 못 쓰는 "키 잠금(key lockout)" 상태가 된다. 그래서 "키 정책 + IAM 정책 둘 다 필요"가 정답이고 "IAM 정책만으로 충분"은 오답이다.

세 번째 축인 Grant는 코드로 임시·세밀한 권한을 부여하는 방법이다. Key Policy나 IAM을 건드리지 않고 "이 principal이 이 키로 Decrypt만, 이 조건에서만" 같은 일회성 권한을 발급한다.

Grant는 AWS 서비스가 사용자 대신 키를 써야 할 때 내부적으로 쓰인다. 예를 들어 암호화된 EBS 볼륨을 EC2에 붙이면, EC2 서비스가 그 볼륨의 CMK에 대해 임시 Grant를 받아 부팅 시 복호화한다. 사용자가 키 정책을 직접 고칠 필요 없이, 서비스가 필요한 순간 최소 권한 Grant를 만들고 작업이 끝나면 폐기하는 패턴이다. Grant는 "최소 권한, 짧은 수명"을 코드로 강제하기 좋은 메커니즘이라 Lambda가 다른 사용자 대신 일시적으로 키를 써야 하는 시나리오에서도 등장한다.

KMS API 한도와 비대칭 키

CMK 한 개의 암호화 API 처리량에는 리전·키 타입별 한도가 있다(대칭 키는 보통 초당 수만 건, us-east-1 등 큰 리전은 더 높다). 이 한도를 넘으면 ThrottlingException이 발생한다. 봉투 암호화가 KMS 호출을 줄여주는 두 번째 이유가 여기 있다 — 데이터마다 KMS를 호출하지 않고 DEK를 재사용·캐싱하면 API 호출 폭증을 막을 수 있다.

KMS는 대칭 키(AES-256) 외에 비대칭 키도 지원한다.

Key Spec종류용도
SYMMETRIC_DEFAULT (AES-256)대칭일반 암호화 (대부분)
RSA_2048 / RSA_3072 / RSA_4096비대칭암호화 + 서명/검증
ECC_NIST_P256 / P384비대칭서명/검증만 (암호화 불가)
HMAC_*대칭 MAC메시지 인증 코드 생성/검증

ECC(타원곡선) 키는 서명·검증만 되고 암호화는 안 된다. ECDSA는 서명 알고리즘이지 암호화 알고리즘이 아니기 때문이다. "데이터를 비대칭 키로 암호화"가 필요하면 RSA를 골라야 한다. 또 비대칭 키는 공개키를 GetPublicKey로 내보낼 수 있어, 외부 시스템이 공개키로 암호화하고 KMS 안에서만 개인키로 복호화하는 시나리오가 가능하다 — 대칭 키와 달리 공개키는 격리 대상이 아니다.

Multi-Region Key와 키 삭제의 안전장치

기본 CMK는 리전에 종속된다. ap-northeast-2에서 암호화한 데이터는 다른 리전의 KMS로는 복호화할 수 없다. 멀티 리전 워크로드(S3 Cross-Region Replication, DynamoDB Global Tables)에서 이게 걸림돌이 되므로, Multi-Region Key는 같은 키 ID를 가진 복제본을 여러 리전에 두어 한 리전에서 암호화한 것을 다른 리전에서 복호화할 수 있게 한다.

키 삭제에는 강력한 안전장치가 있다. ScheduleKeyDeletion을 호출하면 즉시 삭제되지 않고 7~30일의 대기 기간(waiting period) 이 시작된다. 이 기간 동안 키는 PendingDeletion 상태로 사용 불가지만 취소(CancelKeyDeletion)는 가능하다.

CMK가 삭제되면 그 키로 암호화된 모든 데이터가 영구히 복호화 불가능해진다. 백업도 소용없다. 7~30일의 유예는 실수나 악의적 삭제를 되돌릴 창을 제공한다. 즉시 삭제 옵션이 아예 없다는 점이 시험 포인트다.

CloudHSM과의 경계: 언제 KMS로 부족한가

KMS는 멀티테넌트 HSM 위에서 동작한다 — 여러 고객의 키가 논리적으로는 격리되지만 물리적 HSM은 공유된다. 규제가 매우 강한 산업(특정 금융·정부)에서는 "내 키 전용 하드웨어"가 요구되기도 한다. 이때 쓰는 게 CloudHSM이다.

항목KMSCloudHSM
관리완전 관리형고객 관리(클러스터 운영)
격리멀티테넌트(논리적)싱글테넌트(전용 HW)
표준FIPS 140-2 Level 2~3FIPS 140-2 Level 3
APIAWS SDKPKCS#11, JCE, KSP
비용키당 $1 + API인스턴스당 시간 과금

KMS는 CloudHSM을 custom key store로 연결할 수 있다. 이러면 키 재료는 사용자 전용 CloudHSM 클러스터에 보관되고, 평소엔 친숙한 KMS API로 호출하되 실제 암호 연산은 전용 HW에서 일어난다. "KMS의 편의 + CloudHSM의 전용 격리"를 합치는 패턴이다. 시험에서 "키를 AWS가 절대 볼 수 없어야 하고 전용 HW가 필요하다"는 규제 시나리오가 나오면 CloudHSM(또는 KMS custom key store)이 정답이고, 일반적인 "관리형 키 암호화"는 KMS다.

CLI로 만져보기

# 1) CMK 생성 + alias 부여
aws kms create-key --description "myapp prod key"
aws kms create-alias --alias-name alias/myapp-key --target-key-id <key-id>
 
# 2) 자동 회전 활성화 (1년)
aws kms enable-key-rotation --key-id alias/myapp-key
aws kms get-key-rotation-status --key-id alias/myapp-key
 
# 3) 봉투 암호화용 데이터 키 발급
aws kms generate-data-key --key-id alias/myapp-key --key-spec AES_256
 
# 4) 4KB 이하 직접 암호화 (예: 설정 토큰)
aws kms encrypt --key-id alias/myapp-key --plaintext fileb://token.bin --output text --query CiphertextBlob
 
# 5) 키 삭제 예약 (최소 7일 대기)
aws kms schedule-key-deletion --key-id <key-id> --pending-window-in-days 7

정리

KMS가 풀려던 문제는 "키를 절대 평문으로 밖에 내보내지 않으면서도 암호화를 편하게 쓰게 하기"였다. 그 제약에서 4KB 한도가 나왔고, 그 한도를 우회하는 봉투 암호화가 AWS 전체 저장 암호화의 표준이 됐다. 권한은 키 정책이 최종 권위이며 IAM 위임 statement가 빠지면 키가 잠긴다는 점, 키 삭제에 7~30일 유예가 있다는 점, ECC는 서명만 되고 암호화는 RSA라는 점 — 이 미세한 차이들이 시험 함정의 핵심이다.

다음 글에서는 KMS 위에 한 겹 더 얹혀, 비밀의 저장과 자동 회전까지 책임지는 Secrets Manager와, 더 가볍고 계층적인 Parameter Store를 본다.

📝 연습 문제

선택지를 클릭하면 정답·해설이 펼쳐집니다.

문제 1

10MB 파일을 KMS로 암호화하려 한다. 올바른 방법은?

문제 2

Customer Managed Key에 대해 IAM 정책으로 kms:Decrypt를 허용했는데도 복호화가 거부된다. 가장 가능성 높은 원인은?

문제 3

AWS Managed Key(aws/s3 등)의 자동 키 회전 주기는?

문제 4

데이터를 비대칭 키로 암호화해야 하는 요구사항이 있다. 적합한 KMS Key Spec은?

문제 5

실수로 삭제하면 안 되는 프로덕션 CMK가 있다. 키를 삭제 요청했을 때 KMS의 동작은?

문제 6

S3 SSE-KMS로 매일 수백만 개의 객체를 암호화하는 워크로드가 KMS API throttling에 걸린다. 비용과 호출을 줄이는 가장 적합한 방법은?

문제 7

규제 요구사항상 키를 전용 하드웨어에 보관하고 AWS도 키 재료에 접근할 수 없어야 한다. 적합한 선택은?

이전Week 8 종합 복습: CI/CD 파이프라인을 머릿속에서 끝까지 돌려보기Week 8 · Day 5다음 Secrets Manager와 Parameter Store: 비밀을 코드 밖으로 꺼내기Week 9 · Day 2

참고 공식 자료

  • DVA-C02 공식 시험 안내(새 탭에서 열림)
  • AWS KMS 공식 문서(새 탭에서 열림)
  • AWS IAM 공식 문서(새 탭에서 열림)
  • Amazon S3 공식 문서(새 탭에서 열림)
  • AWS Secrets Manager 공식 문서(새 탭에서 열림)
  • Amazon EBS 공식 문서(새 탭에서 열림)

이 페이지

  • KMS가 풀려고 한 문제: 키는 절대 밖으로 나가면 안 된다
  • 봉투 암호화: 키로 키를 암호화하는 두 단계 트릭
  • 키 유형: 누가 키를 소유하고 통제하는가
  • 키 정책 + IAM + Grant: KMS의 3중 권한 모델
  • KMS API 한도와 비대칭 키
  • Multi-Region Key와 키 삭제의 안전장치
  • CloudHSM과의 경계: 언제 KMS로 부족한가
  • CLI로 만져보기
  • 정리
  • 연습 문제