KMS 데이터 암호화
"데이터를 금고에 넣자 - 저장된 데이터를 암호화하여 보호하기"
이 문서는 강사용 답안입니다. 학생에게 공유하지 마세요. 각 단계의 정확한 답과 해설, 트러블슈팅 가이드가 포함되어 있습니다.
Step 1: RDS 암호화 상태 확인
답안
웹 콘솔 방법
- AWS 콘솔에서 RDS 서비스로 이동
- 좌측 메뉴에서 데이터베이스 클릭
- ShopEasy RDS 인스턴스 (예:
shopeasy-db) 클릭 - 구성(Configuration) 탭 클릭
- 스토리지 섹션에서 암호화 항목 확인:
- 활성화됨: 스토리지가 암호화되어 있음 (KMS 키 ARN도 표시됨)
- 비활성화됨: 스토리지가 암호화되지 않음
AWS CLI 방법
# RDS 인스턴스의 암호화 상태 확인
aws rds describe-db-instances \
--query "DBInstances[?DBInstanceIdentifier=='shopeasy-db'].{ID:DBInstanceIdentifier,Encrypted:StorageEncrypted,KmsKey:KmsKeyId}" \
--output table \
--region ap-northeast-2
# 또는 모든 RDS 인스턴스의 암호화 상태 한번에 확인
aws rds describe-db-instances \
--query "DBInstances[].{ID:DBInstanceIdentifier,Engine:Engine,Encrypted:StorageEncrypted,KmsKey:KmsKeyId}" \
--output table \
--region ap-northeast-2
정상 출력 예시 (암호화된 경우):
-------------------------------------------------------------------------------------
| DescribeDBInstances |
+-------------+-----------+--------------------------------------------------------+
| Encrypted | ID | KmsKey |
+-------------+-----------+--------------------------------------------------------+
| True | shopeasy-db | arn:aws:kms:ap-northeast-2:123456789012:key/xxxx-xxxx |
+-------------+-----------+--------------------------------------------------------+
암호화되지 않은 경우:
--------------------------------------
| DescribeDBInstances |
+-------------+-----------+----------+
| Encrypted | ID | KmsKey |
+-------------+-----------+----------+
| False | shopeasy-db | None |
+-------------+-----------+----------+
이미 생성된 암호화되지 않은 RDS 인스턴스에는 암호화를 직접 활성화할 수 없습니다. 다음 과정을 거쳐야 합니다:
- 스냅샷 생성: 현재 DB 인스턴스의 수동 스냅샷을 생성
- 암호화된 스냅샷 복사: 스냅샷을 복사하면서 암호화 옵션을 활성화
- 새 인스턴스 복원: 암호화된 스냅샷에서 새 DB 인스턴스를 복원
- 엔드포인트 변경: 애플리케이션의 DB 연결 엔드포인트를 새 인스턴스로 교체
- 기존 인스턴스 삭제: 확인 후 기존 비암호화 인스턴스 삭제
# [참고용] 암호화되지 않은 RDS를 암호화하는 CLI 과정
# (이번 실습에서는 실행하지 않습니다)
# 1. 스냅샷 생성
aws rds create-db-snapshot \
--db-instance-identifier shopeasy-db \
--db-snapshot-identifier shopeasy-db-snapshot-for-encryption \
--region ap-northeast-2
# 2. 스냅샷 생성 완료 대기
aws rds wait db-snapshot-available \
--db-snapshot-identifier shopeasy-db-snapshot-for-encryption \
--region ap-northeast-2
# 3. 암호화된 스냅샷으로 복사
aws rds copy-db-snapshot \
--source-db-snapshot-identifier shopeasy-db-snapshot-for-encryption \
--target-db-snapshot-identifier shopeasy-db-snapshot-encrypted \
--kms-key-id alias/aws/rds \
--region ap-northeast-2
# 4. 복사 완료 대기
aws rds wait db-snapshot-available \
--db-snapshot-identifier shopeasy-db-snapshot-encrypted \
--region ap-northeast-2
# 5. 암호화된 스냅샷에서 새 인스턴스 복원
aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier shopeasy-db-encrypted \
--db-snapshot-identifier shopeasy-db-snapshot-encrypted \
--region ap-northeast-2
주의: 이 과정은 새 인스턴스를 생성하므로 엔드포인트가 변경됩니다. 또한 다운타임이 발생하며, 추가 비용이 들 수 있습니다. 이번 실습에서는 상태 확인만 수행하고, 실제 변환은 하지 않습니다.
RDS 인스턴스를 처음 생성할 때 반드시 암호화를 활성화해야 합니다.
나중에 변경하려면 매우 번거롭고 다운타임이 발생합니다.
AWS CloudFormation이나 Terraform 등 IaC 도구에서 StorageEncrypted: true를
기본 템플릿에 포함시키는 것이 좋습니다.
Step 2: S3 버킷 기본 암호화 설정
답안
웹 콘솔 방법
- AWS 콘솔에서 S3 서비스로 이동
shopeasy-images-{ACCOUNT_ID}버킷 클릭- 속성(Properties) 탭 클릭
- 기본 암호화(Default encryption) 섹션으로 스크롤
- 편집 클릭
- 암호화 유형 설정:
- 방법 A (SSE-S3): "Amazon S3 관리형 키(SSE-S3)" 선택 → 암호화 알고리즘: AES-256
- 방법 B (SSE-KMS): "AWS Key Management Service 키(SSE-KMS)" 선택 → AWS 관리형 키:
aws/s3
- 버킷 키: 활성화 (SSE-KMS 선택 시 KMS API 호출 비용 절감)
- 변경 사항 저장 클릭
AWS CLI 방법
방법 A: SSE-S3 (AES-256) 설정
# 계정 ID 확인
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
# S3 버킷에 SSE-S3 기본 암호화 설정
aws s3api put-bucket-encryption \
--bucket shopeasy-images-${ACCOUNT_ID} \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
},
"BucketKeyEnabled": true
}]
}'
# 설정 확인
aws s3api get-bucket-encryption \
--bucket shopeasy-images-${ACCOUNT_ID}
방법 B: SSE-KMS (aws/s3 키) 설정
# S3 버킷에 SSE-KMS 기본 암호화 설정
aws s3api put-bucket-encryption \
--bucket shopeasy-images-${ACCOUNT_ID} \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "alias/aws/s3"
},
"BucketKeyEnabled": true
}]
}'
# 설정 확인
aws s3api get-bucket-encryption \
--bucket shopeasy-images-${ACCOUNT_ID}
정상 출력 예시 (SSE-S3의 경우):
{
"ServerSideEncryptionConfiguration": {
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
},
"BucketKeyEnabled": true
}
]
}
}
S3 버킷의 기본 암호화를 설정하면, 업로드 시 암호화 헤더를 지정하지 않은 객체에도 자동으로 서버 측 암호화가 적용됩니다.
- 이미 업로드된 기존 객체에는 소급 적용되지 않습니다 (새로 업로드되는 객체부터 적용)
- 업로드 시 명시적으로 다른 암호화를 지정하면 기본 설정보다 우선됩니다
- BucketKeyEnabled: true는 SSE-KMS 사용 시 S3 버킷 키를 생성하여 KMS API 호출 횟수를 줄여 비용을 절감합니다
shopeasy-frontend-{ACCOUNT_ID} 버킷에도 동일하게 기본 암호화를 설정할 수 있습니다.
프론트엔드 파일(HTML, CSS, JS)은 공개 콘텐츠이지만, 저장 데이터 암호화는 보안 모범 사례입니다.
# 프론트엔드 버킷에도 SSE-S3 기본 암호화 설정
aws s3api put-bucket-encryption \
--bucket shopeasy-frontend-${ACCOUNT_ID} \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
},
"BucketKeyEnabled": true
}]
}'
Step 3: DynamoDB 암호화 확인
답안
웹 콘솔 방법
- AWS 콘솔에서 DynamoDB 서비스로 이동
- 좌측 메뉴에서 테이블 클릭
Reviews테이블 클릭- 추가 설정(Additional settings) 탭 클릭
- 암호화(Encryption) 섹션 확인:
- 암호화 유형: "Amazon DynamoDB가 소유" (기본값) 또는 "AWS 관리형 키" 또는 "고객 관리형 키"
- 기본값인 "Amazon DynamoDB가 소유"는 AWS 소유 키를 사용하는 것을 의미합니다
AWS CLI 방법
# DynamoDB Reviews 테이블의 암호화 상태 확인
aws dynamodb describe-table \
--table-name Reviews \
--query "Table.SSEDescription" \
--region ap-northeast-2
출력 결과 해석:
# 경우 1: AWS 소유 키 사용 (기본값)
# SSEDescription이 null로 반환됩니다
null
# 경우 2: AWS 관리형 키 (aws/dynamodb) 사용
{
"Status": "ENABLED",
"SSEType": "KMS",
"KMSMasterKeyArn": "arn:aws:kms:ap-northeast-2:123456789012:key/xxxx-xxxx"
}
# 경우 3: 고객 관리형 키 사용
{
"Status": "ENABLED",
"SSEType": "KMS",
"KMSMasterKeyArn": "arn:aws:kms:ap-northeast-2:123456789012:key/yyyy-yyyy"
}
CLI에서 SSEDescription이 null로 반환되면, 이는 암호화가 안 되어 있다는 의미가 아닙니다.
DynamoDB의 기본 암호화인 AWS 소유 키를 사용하고 있다는 뜻입니다.
DynamoDB는 모든 데이터를 항상 암호화합니다. SSEDescription에 값이 있는 경우는
기본 AWS 소유 키 대신 KMS 관리형 키 또는 고객 관리형 키를 명시적으로 선택한 경우뿐입니다.
| 키 유형 | 비용 | CloudTrail 감사 | 키 관리 |
|---|---|---|---|
| AWS 소유 키 (기본값) | 무료 | 불가 | AWS가 완전 관리 |
| AWS 관리형 키 (aws/dynamodb) | 무료 | 가능 | AWS가 관리, 사용자가 확인 가능 |
| 고객 관리형 키 (CMK) | $1/월 + API 호출 | 가능 | 사용자가 직접 관리 |
Step 4: KMS 키 확인
답안
웹 콘솔 방법
- AWS 콘솔에서 KMS (Key Management Service) 서비스로 이동
- 좌측 메뉴에서 AWS 관리형 키 클릭
- 다음과 같은 키 목록이 표시됩니다 (사용한 서비스에 따라 다름):
aws/rds- RDS 암호화에 사용되는 키aws/s3- S3 SSE-KMS 암호화에 사용되는 키aws/dynamodb- DynamoDB KMS 암호화에 사용되는 키aws/ebs- EBS 볼륨 암호화에 사용되는 키
- 각 키를 클릭하면 키 ID, ARN, 생성 날짜, 키 정책 등을 확인할 수 있습니다
- 좌측 메뉴에서 고객 관리형 키를 클릭하면 직접 생성한 키 목록을 확인할 수 있습니다 (이번 실습에서는 없을 수 있음)
AWS CLI 방법
# AWS 관리형 키 목록 확인 (aws/로 시작하는 별칭)
aws kms list-aliases \
--query "Aliases[?contains(AliasName,'aws/')].[AliasName,TargetKeyId]" \
--output table \
--region ap-northeast-2
정상 출력 예시:
--------------------------------------------------------------
| ListAliases |
+-------------------+----------------------------------------+
| aws/dynamodb | abcd1234-5678-90ef-ghij-klmnopqrstuv |
| aws/ebs | bcde2345-6789-01fg-hijk-lmnopqrstuvw |
| aws/rds | cdef3456-7890-12gh-ijkl-mnopqrstuvwx |
| aws/s3 | defg4567-8901-23hi-jklm-nopqrstuvwxy |
+-------------------+----------------------------------------+
# 모든 별칭(alias) 목록 확인 (관리형 + 고객 관리형)
aws kms list-aliases \
--query "Aliases[].[AliasName,TargetKeyId]" \
--output table \
--region ap-northeast-2
# 특정 키의 상세 정보 확인 (예: aws/s3)
aws kms describe-key \
--key-id alias/aws/s3 \
--query "KeyMetadata.{KeyId:KeyId,KeyState:KeyState,KeyManager:KeyManager,CreationDate:CreationDate,Description:Description}" \
--region ap-northeast-2
# 고객 관리형 키만 확인
aws kms list-keys \
--region ap-northeast-2 \
--query "Keys[].KeyId" \
--output table
AWS 관리형 키는 해당 서비스에서 암호화를 처음 사용할 때 자동으로 생성됩니다.
aws/rds가 없다면: 아직 RDS에서 KMS 암호화를 사용한 적이 없음aws/s3가 없다면: 아직 S3에서 SSE-KMS를 사용한 적이 없음 (SSE-S3는 KMS를 사용하지 않음)aws/dynamodb가 없다면: DynamoDB에서 AWS 관리형 키를 선택한 적이 없음 (기본 AWS 소유 키는 KMS 콘솔에 표시되지 않음)
키가 보이지 않는 것은 정상입니다. 이번 실습에서 S3에 SSE-KMS를 설정했다면 aws/s3 키가 새로 생성되어 있을 것입니다.
| 서비스 | 기본 암호화 | 사용되는 키 | 비용 |
|---|---|---|---|
| RDS | 생성 시 선택 (기본: 비활성화) | aws/rds (선택 시) | 무료 |
| S3 (SSE-S3) | 2023.01~ 자동 적용 | S3 자체 관리 키 | 무료 |
| S3 (SSE-KMS) | 수동 설정 | aws/s3 | 무료 (관리형 키) |
| DynamoDB | 항상 활성화 (비활성화 불가) | AWS 소유 키 (기본) | 무료 |
트러블슈팅 가이드
자주 발생하는 문제와 해결 방법
원인: 아직 해당 리전에서 KMS 암호화를 사용하는 서비스를 한 번도 사용하지 않았음
해결 방법:
- 리전이
ap-northeast-2(서울)로 설정되어 있는지 확인 - AWS 관리형 키는 해당 서비스에서 암호화를 처음 사용할 때 자동 생성됩니다
- Step 2에서 S3 버킷에 SSE-KMS를 설정하면
aws/s3키가 생성됩니다 - 키가 없어도 정상 - 서비스를 사용하면 자동으로 만들어집니다
원인: IAM 사용자에게 S3 또는 KMS 관련 권한이 부족
해결 방법:
- 현재 로그인한 IAM 사용자의 권한을 확인합니다
s3:PutEncryptionConfiguration권한이 필요합니다- SSE-KMS를 설정하는 경우
kms:DescribeKey,kms:GenerateDataKey권한도 필요합니다
# 현재 사용자 확인
aws sts get-caller-identity
# S3 버킷 암호화 설정 권한 테스트
aws s3api get-bucket-encryption \
--bucket shopeasy-images-${ACCOUNT_ID}
원인: RDS 인스턴스 생성 시 암호화 옵션을 선택하지 않았음
해결 방법:
- 이것은 정상적인 상황입니다 (이전 챕터에서 암호화 없이 생성한 경우)
- 이미 생성된 인스턴스에는 직접 암호화를 켤 수 없습니다
- 실습에서는 상태 확인 후 "스냅샷 복사 방식으로 암호화 적용 가능"이라는 개념만 이해하면 됩니다
- 시간과 비용이 허락한다면 Step 1의 해설에 있는 스냅샷 방식으로 변환 가능합니다
원인: DynamoDB가 기본 AWS 소유 키를 사용하고 있음 (정상)
해결 방법:
- 이것은 정상적인 결과입니다
- DynamoDB는 항상 암호화되어 있습니다 (비활성화 불가)
SSEDescription이 null이면 기본 AWS 소유 키를 사용한다는 의미입니다- AWS 관리형 키(aws/dynamodb)나 고객 관리형 키를 명시적으로 설정한 경우에만 값이 표시됩니다
# DynamoDB 테이블 전체 정보 확인
aws dynamodb describe-table \
--table-name Reviews \
--region ap-northeast-2 \
--query "Table.{Name:TableName,Status:TableStatus,SSE:SSEDescription}"
# 출력 예시 (기본 암호화 - 정상):
# {
# "Name": "Reviews",
# "Status": "ACTIVE",
# "SSE": null <-- null이지만 암호화는 되어 있음!
# }
원인: S3 기본 암호화는 설정 이후 새로 업로드되는 객체에만 적용됨
해결 방법:
- 기본 암호화 설정은 새로 업로드되는 객체에만 자동 적용됩니다
- 기존 객체를 암호화하려면 해당 객체를 다시 업로드(덮어쓰기)해야 합니다
- S3 Batch Operations 또는
aws s3 cp명령으로 일괄 처리 가능합니다
# 기존 객체를 SSE-S3로 다시 암호화 (동일 위치에 복사)
aws s3 cp \
s3://shopeasy-images-${ACCOUNT_ID}/ \
s3://shopeasy-images-${ACCOUNT_ID}/ \
--recursive \
--sse AES256
# 특정 객체의 암호화 상태 확인
aws s3api head-object \
--bucket shopeasy-images-${ACCOUNT_ID} \
--key uploads/test-image.png \
--query "ServerSideEncryption"
원인: EC2 IAM Role에 KMS 키 사용 권한이 없음
해결 방법:
- SSE-KMS로 암호화된 객체를 읽으려면 해당 KMS 키에 대한
kms:Decrypt권한이 필요합니다 - AWS 관리형 키(aws/s3)를 사용하는 경우, 동일 계정 내에서는 보통 자동으로 권한이 있습니다
- 문제가 지속되면 SSE-S3(AES-256)으로 변경하세요 - SSE-S3는 별도 KMS 권한이 필요 없습니다
# SSE-S3로 변경 (KMS 권한 문제 회피)
aws s3api put-bucket-encryption \
--bucket shopeasy-images-${ACCOUNT_ID} \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
},
"BucketKeyEnabled": true
}]
}'
- DynamoDB SSEDescription이 null = 암호화 안됨? - 아닙니다! AWS 소유 키로 항상 암호화되어 있습니다. null은 기본 키를 사용한다는 의미입니다.
- S3 기본 암호화 = 기존 파일도 자동 암호화? - 아닙니다. 기본 암호화는 새로 업로드되는 객체에만 적용됩니다. 기존 객체는 별도 작업이 필요합니다.
- RDS 암호화를 나중에 켤 수 있나요? - 직접 켤 수 없습니다. 스냅샷 → 암호화 복사 → 복원 과정이 필요합니다. 처음부터 암호화를 켜는 것이 중요합니다.
- SSE-S3와 SSE-KMS 중 어떤 것을 선택? - 특별한 규제 요구사항이 없다면 SSE-S3(AES-256)으로 충분합니다. CloudTrail 감사 로그가 필요하면 SSE-KMS를 사용하세요.
- 암호화하면 성능이 떨어지나요? - AWS 서비스의 서버 측 암호화는 성능에 거의 영향을 주지 않습니다. AWS가 하드웨어 수준에서 최적화하기 때문입니다.