본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 20. · 7 Views
AWS KMS 암호화 완벽 가이드
AWS KMS(Key Management Service)를 활용한 클라우드 데이터 암호화 방법을 초급 개발자를 위해 쉽게 설명합니다. CMK 생성부터 S3, EBS 암호화, 봉투 암호화까지 실무에 필요한 모든 내용을 담았습니다.
목차
1. KMS란 무엇인가
입사 2개월 차 김개발 씨는 오늘 처음으로 프로덕션 환경에 데이터를 배포하는 임무를 맡았습니다. 그런데 선배 박시니어 씨가 갑자기 물었습니다.
"저기, 민감한 데이터는 암호화했어요?" 김개발 씨는 당황했습니다. 암호화를 어떻게 해야 하는지 전혀 몰랐거든요.
AWS KMS는 클라우드에서 암호화 키를 안전하게 관리해주는 서비스입니다. 마치 은행의 금고처럼 여러분의 데이터를 암호화하는 열쇠를 안전하게 보관하고 관리합니다.
직접 암호화 키를 관리하는 복잡함 없이 AWS가 제공하는 강력한 보안 기능을 활용할 수 있습니다.
다음 코드를 살펴봅시다.
import boto3
# KMS 클라이언트 생성
kms = boto3.client('kms', region_name='ap-northeast-2')
# 평문 데이터 암호화
plaintext = "민감한 고객 정보"
response = kms.encrypt(
KeyId='arn:aws:kms:ap-northeast-2:123456789012:key/abcd1234',
Plaintext=plaintext.encode('utf-8')
)
# 암호화된 데이터 가져오기
ciphertext = response['CiphertextBlob']
print(f"암호화 완료: {len(ciphertext)} bytes")
김개발 씨는 당황한 표정으로 선배에게 물었습니다. "암호화요?
그게 뭔가요?" 박시니어 씨가 웃으며 설명을 시작했습니다. "아, 신입이니까 모를 수 있지.
자, 이렇게 생각해봐. 네가 중요한 편지를 보낸다고 생각해보자." 그렇다면 KMS란 정확히 무엇일까요?
쉽게 비유하자면, KMS는 마치 은행의 금고와 같습니다. 여러분이 소중한 보석을 은행 금고에 맡기면 은행이 안전하게 보관해주듯이, KMS도 여러분의 암호화 키를 안전하게 보관하고 관리합니다.
금고 열쇠는 은행이 철저하게 관리하고, 여러분은 필요할 때마다 인증을 거쳐 금고에 접근할 수 있습니다. KMS가 없던 시절에는 어땠을까요?
개발자들은 암호화 키를 직접 생성하고 관리해야 했습니다. 키를 어디에 저장할지, 어떻게 안전하게 보관할지, 키가 유출되지 않도록 어떻게 방지할지 모든 것을 직접 고민해야 했습니다.
더 큰 문제는 키를 주기적으로 교체하고, 누가 언제 어떤 키를 사용했는지 추적하는 일이었습니다. 프로젝트가 커질수록 이런 관리 부담은 눈덩이처럼 불어났습니다.
바로 이런 문제를 해결하기 위해 AWS KMS가 등장했습니다. KMS를 사용하면 암호화 키를 직접 관리할 필요가 없습니다.
AWS가 업계 표준 암호화 알고리즘을 사용하여 키를 생성하고, 물리적으로 안전한 하드웨어에 저장합니다. 또한 누가 언제 어떤 키를 사용했는지 모든 로그가 자동으로 기록됩니다.
무엇보다 키를 주기적으로 자동 교체할 수 있다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 boto3.client('kms')로 KMS 서비스와 연결합니다. 이 부분이 핵심입니다.
다음으로 encrypt() 메서드를 호출하면서 암호화할 데이터와 사용할 키의 ID를 전달합니다. KMS는 지정된 키를 사용하여 데이터를 암호화하고, 암호문을 반환합니다.
중요한 점은 실제 암호화 키는 절대 여러분의 코드로 전달되지 않는다는 것입니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 전자상거래 서비스를 개발한다고 가정해봅시다. 고객의 신용카드 정보나 개인정보를 데이터베이스에 저장할 때 KMS를 활용하면 자동으로 암호화되어 저장됩니다.
설령 데이터베이스가 해킹당하더라도 암호화 키 없이는 데이터를 읽을 수 없습니다. 삼성, 카카오, 네이버 같은 많은 기업에서 이런 패턴을 적극적으로 사용하고 있습니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 암호화 키 ID를 코드에 하드코딩하는 것입니다.
이렇게 하면 환경이 바뀔 때마다 코드를 수정해야 하는 문제가 발생합니다. 따라서 환경 변수나 AWS Systems Manager Parameter Store를 사용하여 키 ID를 관리하는 것이 올바른 방법입니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.
"아, 그래서 KMS를 사용하는 거군요!" AWS KMS를 제대로 이해하면 복잡한 암호화 로직을 직접 구현하지 않고도 엔터프라이즈급 보안을 구현할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - KMS 사용 비용은 키 개수와 API 호출 횟수로 책정되므로, 불필요한 키는 삭제하세요
- 중요한 키는 삭제 예약 기간(7-30일)을 설정하여 실수로 삭제되는 것을 방지할 수 있습니다
- CloudTrail을 활성화하면 모든 KMS 작업이 로그로 남아 보안 감사에 유용합니다
2. CMK 생성하기
다음 날 김개발 씨는 본격적으로 KMS를 사용하기로 했습니다. 그런데 막상 AWS 콘솔을 열어보니 어디서부터 시작해야 할지 막막했습니다.
"CMK? Customer Master Key?
이게 뭐지?" 다시 한번 박시니어 씨를 찾아갔습니다.
CMK(Customer Master Key)는 KMS의 핵심이 되는 암호화 키입니다. 마치 건물의 마스터 키처럼 다른 모든 데이터 암호화 키를 관리하는 최상위 키입니다.
CMK는 AWS가 관리하는 키와 고객이 직접 관리하는 키로 나뉘며, 용도에 따라 적절한 타입을 선택할 수 있습니다.
다음 코드를 살펴봅시다.
import boto3
kms = boto3.client('kms', region_name='ap-northeast-2')
# CMK 생성
response = kms.create_key(
Description='고객 데이터 암호화용 마스터 키',
KeyUsage='ENCRYPT_DECRYPT', # 암호화/복호화 용도
Origin='AWS_KMS', # AWS가 키 자료 생성
MultiRegion=False # 단일 리전 키
)
key_id = response['KeyMetadata']['KeyId']
print(f"CMK 생성 완료: {key_id}")
# 키에 별칭 추가 (관리 편의성)
kms.create_alias(
AliasName='alias/customer-data-key',
TargetKeyId=key_id
)
박시니어 씨가 모니터 앞에 앉으며 설명을 시작했습니다. "자, CMK 생성은 생각보다 간단해.
하지만 제대로 이해하고 만들어야 해." 그렇다면 CMK란 정확히 무엇일까요? 쉽게 비유하자면, CMK는 마치 아파트 관리실의 마스터 키와 같습니다.
관리실에는 모든 세대의 열쇠를 보관하는 마스터 키가 있죠. 각 세대마다 고유한 열쇠가 있지만, 긴급한 상황에서는 마스터 키로 모든 문을 열 수 있습니다.
이처럼 CMK도 실제 데이터를 암호화하는 데이터 키들을 관리하는 최상위 키입니다. CMK를 직접 생성하지 않고 기본 키만 사용하면 어떤 문제가 있을까요?
AWS는 각 서비스마다 기본 관리형 키를 제공합니다. 하지만 이 키들은 모든 사용자가 공유하는 키이기 때문에 세밀한 권한 관리가 불가능합니다.
또한 키를 삭제하거나 교체할 수도 없습니다. 더 큰 문제는 감사 로그를 분석할 때 어떤 애플리케이션이 암호화를 수행했는지 구분하기 어렵다는 점입니다.
바로 이런 문제를 해결하기 위해 고객 관리형 CMK를 직접 생성합니다. 고객 관리형 CMK를 생성하면 키에 대한 완전한 통제권을 갖게 됩니다.
누가 이 키를 사용할 수 있는지 세밀하게 설정할 수 있습니다. 또한 키를 언제든지 비활성화하거나 삭제 예약을 할 수 있습니다.
무엇보다 자동 키 교체 기능을 활성화하여 매년 새로운 키로 자동 교체되도록 설정할 수 있다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 create_key() 메서드를 호출하면서 키의 용도를 지정합니다. KeyUsage='ENCRYPT_DECRYPT'는 이 키가 암호화와 복호화 용도로 사용된다는 의미입니다.
Origin='AWS_KMS'는 AWS가 안전한 방식으로 키 자료를 생성한다는 뜻입니다. 마지막으로 키가 생성되면 고유한 ID가 반환되는데, 이 ID만으로는 관리가 어려우므로 create_alias()로 읽기 쉬운 별칭을 붙여줍니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 금융 서비스를 개발한다고 가정해봅시다.
고객의 계좌 정보를 암호화할 때는 'alias/account-encryption-key'라는 별칭의 CMK를 사용하고, 거래 내역을 암호화할 때는 'alias/transaction-encryption-key'를 사용하는 식으로 용도별로 키를 분리합니다. 이렇게 하면 나중에 특정 데이터 유형에 문제가 생겼을 때 해당 키만 교체하면 됩니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 모든 데이터에 하나의 CMK만 사용하는 것입니다.
이렇게 하면 키가 손상되었을 때 모든 데이터가 위험에 노출됩니다. 따라서 데이터의 중요도와 용도에 따라 여러 개의 CMK를 생성하여 사용하는 것이 올바른 방법입니다.
CMK를 생성할 때는 또 하나 중요한 선택이 있습니다. 바로 대칭키와 비대칭키의 선택입니다.
대칭키는 암호화와 복호화에 같은 키를 사용하며 속도가 빠릅니다. 비대칭키는 공개키와 개인키를 사용하며 디지털 서명 등에 활용됩니다.
대부분의 경우 대칭키로 충분합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 설명을 들은 김개발 씨는 직접 CMK를 생성해보았습니다. "오, 생각보다 간단하네요!" CMK 생성은 KMS 활용의 첫걸음입니다.
처음에는 어렵게 느껴질 수 있지만, 한 번 이해하고 나면 매우 직관적입니다. 여러분도 오늘 배운 내용을 바탕으로 프로젝트에 맞는 CMK를 설계해 보세요.
실전 팁
💡 - CMK 생성 시 태그를 활용하면 비용 관리와 리소스 추적이 쉬워집니다
- 자동 키 교체는
enable_key_rotation()메서드로 활성화할 수 있으며, 매년 자동으로 새 키로 교체됩니다 - 멀티 리전 키는 글로벌 서비스에 유용하지만 비용이 더 발생하므로 필요한 경우에만 사용하세요
3. 키 정책 설정
CMK를 생성한 김개발 씨는 신이 났습니다. 드디어 암호화를 적용할 수 있게 되었으니까요.
그런데 다른 팀원이 이 키를 사용하려고 하자 권한 에러가 발생했습니다. "Access Denied?
왜 안 되는 거지?" 김개발 씨는 다시 한번 고민에 빠졌습니다.
키 정책은 누가 CMK를 사용할 수 있는지 제어하는 권한 설정입니다. 마치 건물 출입증처럼 특정 사람에게만 키 사용 권한을 부여하고, 다른 사람은 차단할 수 있습니다.
IAM 정책과 함께 작동하며, 키에 대한 세밀한 접근 제어를 가능하게 합니다.
다음 코드를 살펴봅시다.
import boto3
import json
kms = boto3.client('kms')
# 키 정책 정의
key_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789012:root"},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow use of the key for encryption",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789012:role/AppServerRole"},
"Action": ["kms:Encrypt", "kms:Decrypt", "kms:GenerateDataKey"],
"Resource": "*"
}
]
}
# 키 정책 적용
kms.put_key_policy(
KeyId='alias/customer-data-key',
PolicyName='default',
Policy=json.dumps(key_policy)
)
박시니어 씨가 김개발 씨의 화면을 보더니 웃었습니다. "아, 키 정책을 설정하지 않았구나.
CMK를 만들기만 하고 누가 사용할지 정하지 않으면 당연히 안 되지." 그렇다면 키 정책이란 정확히 무엇일까요? 쉽게 비유하자면, 키 정책은 마치 회사의 보안 출입 시스템과 같습니다.
회사 건물에 들어가려면 출입증이 필요하죠. 일반 직원은 자기 층만 출입할 수 있고, 관리자는 모든 층에 출입할 수 있습니다.
청소 업체 직원은 특정 시간에만 출입할 수 있습니다. 이처럼 키 정책도 각 사용자나 역할에게 서로 다른 권한을 부여할 수 있습니다.
키 정책 없이 CMK만 생성하면 어떤 문제가 발생할까요? 기본적으로 CMK를 생성한 계정의 루트 사용자만 모든 권한을 갖습니다.
다른 IAM 사용자나 역할은 아무리 관리자 권한이 있어도 키를 사용할 수 없습니다. 프로젝트 팀원들이 각자의 역할로 키를 사용해야 하는데 모두 막혀버리는 것입니다.
더 큰 문제는 나중에 누가 실수로 키를 삭제하거나 잘못 사용할 위험이 있다는 점입니다. 바로 이런 문제를 해결하기 위해 키 정책을 설정합니다.
키 정책을 설정하면 특정 IAM 역할에게만 암호화 권한을 주고, 다른 역할에게는 복호화 권한만 줄 수 있습니다. 또한 키 관리 권한과 사용 권한을 분리할 수 있습니다.
무엇보다 조직의 보안 정책에 맞춰 최소 권한 원칙을 적용할 수 있다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 key_policy 딕셔너리를 정의합니다. 첫 번째 Statement는 루트 계정에게 모든 권한을 부여하여 나중에 정책을 수정할 수 있게 합니다.
이 부분이 핵심입니다. 두 번째 Statement는 'AppServerRole'이라는 역할에게 암호화, 복호화, 데이터 키 생성 권한만 부여합니다.
마지막으로 put_key_policy()를 호출하여 정책을 실제로 적용합니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 웹 애플리케이션을 개발한다고 가정해봅시다. 프론트엔드 서버는 데이터를 암호화만 할 수 있고, 백엔드 서버는 복호화만 할 수 있도록 권한을 분리합니다.
데이터베이스 관리자는 키를 관리할 수 있지만 직접 사용할 수는 없도록 설정합니다. 이렇게 역할 기반으로 권한을 분리하면 보안 사고가 발생해도 피해 범위를 최소화할 수 있습니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 키 정책에서 루트 계정 권한을 제거하는 것입니다.
이렇게 하면 나중에 정책을 수정할 방법이 없어져서 AWS 고객 지원팀에 연락해야 하는 상황이 발생할 수 있습니다. 따라서 루트 계정에 대한 관리 권한은 항상 유지하는 것이 올바른 방법입니다.
키 정책에는 **조건(Condition)**도 추가할 수 있습니다. 예를 들어 특정 IP 대역에서만 키를 사용할 수 있도록 제한하거나, 특정 시간대에만 암호화 작업을 허용할 수 있습니다.
또한 MFA(다중 인증)를 요구하도록 설정하여 보안을 더욱 강화할 수 있습니다. 키 정책과 IAM 정책의 차이도 이해해야 합니다.
IAM 정책은 사용자나 역할에 붙는 권한이고, 키 정책은 키 자체에 붙는 권한입니다. 실제로 키를 사용하려면 두 정책이 모두 허용해야 합니다.
마치 건물에 들어가려면 출입증도 있어야 하고, 건물 보안 시스템도 출입을 허용해야 하는 것과 같습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 도움으로 키 정책을 설정한 김개발 씨는 팀원들이 정상적으로 키를 사용할 수 있게 되었습니다. "정책만 잘 설정하면 보안과 편의성을 모두 잡을 수 있네요!" 키 정책은 KMS 보안의 핵심입니다.
처음에는 JSON 문법이 어렵게 느껴질 수 있지만, 기본 패턴을 익히면 다양한 보안 요구사항을 유연하게 처리할 수 있습니다. 여러분도 오늘 배운 내용을 바탕으로 프로젝트에 맞는 키 정책을 설계해 보세요.
실전 팁
💡 - 키 정책은 JSON 형식이므로 문법 오류가 발생하기 쉽습니다. AWS Policy Generator를 사용하면 실수를 줄일 수 있습니다
- 키 정책 변경 전에는 반드시 기존 정책을 백업하세요.
get_key_policy()로 현재 정책을 조회할 수 있습니다 - CloudTrail 로그를 정기적으로 확인하여 키 사용 패턴과 권한 거부 이벤트를 모니터링하세요
4. S3 암호화
키 정책까지 마스터한 김개발 씨는 이제 실전에 적용할 차례입니다. 회사에서 고객이 업로드한 파일을 S3에 저장하는 기능을 개발하고 있었는데, 보안팀에서 "업로드되는 파일은 반드시 암호화해야 합니다"라는 메일이 왔습니다.
"S3 암호화? KMS를 어떻게 연결하지?"
S3 서버 측 암호화는 파일이 S3에 저장될 때 자동으로 암호화되도록 하는 기능입니다. KMS CMK를 사용하면 업로드되는 모든 객체가 자동으로 암호화되며, 다운로드할 때는 자동으로 복호화됩니다.
코드 한 줄만 추가하면 강력한 암호화를 적용할 수 있습니다.
다음 코드를 살펴봅시다.
import boto3
s3 = boto3.client('s3')
# S3 버킷에 기본 암호화 설정
s3.put_bucket_encryption(
Bucket='customer-files-bucket',
ServerSideEncryptionConfiguration={
'Rules': [
{
'ApplyServerSideEncryptionByDefault': {
'SSEAlgorithm': 'aws:kms',
'KMSMasterKeyID': 'alias/customer-data-key'
},
'BucketKeyEnabled': True # 비용 절감을 위한 버킷 키 사용
}
]
}
)
# 파일 업로드 시 암호화 지정
s3.put_object(
Bucket='customer-files-bucket',
Key='uploads/user-document.pdf',
Body=open('document.pdf', 'rb'),
ServerSideEncryption='aws:kms',
SSEKMSKeyId='alias/customer-data-key'
)
박시니어 씨가 김개발 씨의 자리로 다가왔습니다. "S3 암호화?
그거 정말 간단해. KMS와 연결만 하면 돼." 그렇다면 S3 서버 측 암호화란 정확히 무엇일까요?
쉽게 비유하자면, S3 암호화는 마치 은행의 자동 금고 시스템과 같습니다. 여러분이 귀중품을 맡기면 은행 직원이 자동으로 금고에 넣고 잠그는 것처럼, S3도 파일을 업로드하면 자동으로 암호화하여 저장합니다.
파일을 가져올 때도 자동으로 열쇠를 풀어주니 여러분은 암호화 과정을 전혀 신경 쓸 필요가 없습니다. S3 암호화를 사용하지 않으면 어떤 문제가 있을까요?
데이터가 평문으로 저장됩니다. S3 버킷 권한 설정에 실수가 있거나, 내부자가 악의적으로 접근하면 데이터가 그대로 노출됩니다.
실제로 수많은 기업이 잘못 설정된 S3 버킷 때문에 고객 정보를 유출하는 사고를 겪었습니다. 규정 준수 측면에서도 문제가 됩니다.
금융, 의료, 개인정보를 다루는 서비스는 법적으로 암호화가 필수이기 때문입니다. 바로 이런 문제를 해결하기 위해 S3 KMS 암호화를 사용합니다.
S3 버킷에 기본 암호화를 설정하면 누가 업로드하든, 어떤 방법으로 업로드하든 모든 파일이 자동으로 암호화됩니다. 개발자가 실수로 암호화 옵션을 빼먹어도 걱정 없습니다.
또한 CloudTrail과 연동하여 누가 언제 어떤 파일에 접근했는지 감사 로그를 자동으로 남길 수 있습니다. 무엇보다 성능 저하 없이 투명하게 작동한다는 큰 이점이 있습니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 put_bucket_encryption()으로 버킷 전체에 기본 암호화를 설정합니다.
SSEAlgorithm을 'aws:kms'로 지정하면 KMS를 사용한다는 의미입니다. KMSMasterKeyID에는 앞서 생성한 CMK의 별칭을 지정합니다.
BucketKeyEnabled를 True로 설정하면 S3가 임시 데이터 키를 재사용하여 KMS API 호출 횟수를 줄여 비용을 절감할 수 있습니다. 파일을 업로드할 때도 ServerSideEncryption 파라미터로 암호화를 명시할 수 있습니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 사용자가 프로필 사진을 업로드하는 소셜 미디어 서비스를 개발한다고 가정해봅시다.
사용자들은 매일 수천 개의 이미지를 업로드합니다. S3 버킷에 KMS 암호화를 설정해두면 모든 이미지가 자동으로 암호화되어 저장됩니다.
나중에 이미지를 보여줄 때도 S3가 자동으로 복호화하여 전송하므로 애플리케이션 코드는 전혀 변경할 필요가 없습니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 객체마다 다른 암호화 설정을 사용하는 것입니다. 일부 파일은 KMS로, 일부는 S3 관리형 키로, 일부는 암호화 없이 저장하면 나중에 관리가 매우 복잡해집니다.
따라서 버킷 전체에 일관된 암호화 정책을 적용하는 것이 올바른 방법입니다. S3 암호화에는 세 가지 옵션이 있습니다.
SSE-S3는 S3가 관리하는 키로 암호화하며 가장 간단하지만 키 관리 제어권이 없습니다. SSE-KMS는 KMS CMK를 사용하며 키 관리와 감사 로그를 제공합니다.
SSE-C는 고객이 직접 키를 제공하는 방식으로 완전한 통제권을 갖지만 키 관리 부담이 큽니다. 대부분의 경우 SSE-KMS가 보안과 편의성의 균형이 가장 좋습니다.
버킷 키 기능도 이해해야 합니다. 일반적으로 S3는 객체마다 KMS를 호출하여 데이터 키를 생성합니다.
하루에 수백만 개의 파일을 처리하면 KMS API 비용이 상당히 발생할 수 있습니다. 버킷 키를 활성화하면 S3가 버킷 수준의 임시 키를 생성하고 재사용하여 KMS 호출을 99% 이상 줄일 수 있습니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. S3 암호화를 적용한 김개발 씨는 보안팀의 승인을 받았습니다.
"설정 한 번으로 모든 파일이 자동 암호화되다니, 정말 편리하네요!" S3 KMS 암호화는 클라우드 스토리지 보안의 기본입니다. 애플리케이션 코드를 거의 변경하지 않고도 엔터프라이즈급 암호화를 적용할 수 있습니다.
여러분도 오늘 배운 내용을 바탕으로 S3 버킷에 암호화를 적용해 보세요.
실전 팁
💡 - 버킷 정책으로 암호화되지 않은 객체의 업로드를 차단할 수 있습니다. "s3:x-amz-server-side-encryption": "aws:kms" 조건을 추가하세요
- 기존 암호화되지 않은 객체는 S3 Batch Operations를 사용하여 일괄 암호화할 수 있습니다
- S3 Access Analyzer를 활성화하면 퍼블릭 접근 가능한 버킷을 자동으로 탐지할 수 있습니다
5. EBS 암호화
S3 암호화를 성공적으로 적용한 김개발 씨는 자신감이 붙었습니다. 그런데 이번에는 데이터베이스 서버의 디스크를 암호화해야 한다는 요구사항이 들어왔습니다.
"EBS 볼륨 암호화? S3와 비슷한 건가?" 궁금증을 안고 다시 공부를 시작했습니다.
EBS 볼륨 암호화는 EC2 인스턴스에 연결된 디스크를 암호화하는 기능입니다. 데이터베이스 파일, 로그 파일, 임시 파일 등 디스크에 저장되는 모든 데이터가 자동으로 암호화됩니다.
인스턴스 내부에서는 평문처럼 보이지만 실제로는 하드웨어 수준에서 암호화되어 저장됩니다.
다음 코드를 살펴봅시다.
import boto3
ec2 = boto3.client('ec2', region_name='ap-northeast-2')
# 암호화된 EBS 볼륨 생성
response = ec2.create_volume(
AvailabilityZone='ap-northeast-2a',
Size=100, # 100GB
VolumeType='gp3', # General Purpose SSD
Encrypted=True, # 암호화 활성화
KmsKeyId='alias/customer-data-key' # 사용할 CMK 지정
)
volume_id = response['VolumeId']
print(f"암호화된 볼륨 생성: {volume_id}")
# 계정 수준에서 기본 암호화 활성화
ec2.enable_ebs_encryption_by_default()
# 기본 암호화에 사용할 CMK 지정
ec2.modify_ebs_default_kms_key_id(
KmsKeyId='alias/customer-data-key'
)
박시니어 씨가 설명을 시작했습니다. "S3는 파일 저장소고, EBS는 서버의 하드디스크라고 생각하면 돼.
암호화 방식은 비슷하지만 용도가 다르지." 그렇다면 EBS 볼륨 암호화란 정확히 무엇일까요? 쉽게 비유하자면, EBS 암호화는 마치 금고에 넣는 노트북과 같습니다.
노트북 자체는 평소처럼 사용할 수 있지만, 금고 안에 있을 때는 잠겨 있습니다. 누군가 금고를 훔쳐가더라도 내용물을 볼 수 없습니다.
이처럼 EBS도 EC2 인스턴스에서는 일반 디스크처럼 작동하지만, 물리적 디스크에는 암호화되어 저장됩니다. EBS 암호화를 사용하지 않으면 어떤 문제가 있을까요?
디스크에 저장된 데이터가 평문으로 남아있습니다. 만약 물리적 서버에 문제가 생겨서 디스크를 교체하거나 폐기할 때, 데이터가 그대로 남아있으면 유출 위험이 있습니다.
데이터베이스 파일, 애플리케이션 로그, 캐시 파일 등에는 민감한 정보가 포함되어 있을 수 있습니다. 규정 준수 관점에서도 디스크 암호화는 필수 요구사항인 경우가 많습니다.
바로 이런 문제를 해결하기 위해 EBS KMS 암호화를 사용합니다. EBS 암호화를 활성화하면 디스크 전체가 암호화됩니다.
데이터뿐만 아니라 볼륨의 스냅샷도 자동으로 암호화됩니다. 암호화된 스냅샷으로 새 볼륨을 생성하면 자동으로 암호화된 볼륨이 만들어집니다.
무엇보다 성능 오버헤드가 거의 없다는 큰 이점이 있습니다. AWS는 하드웨어 수준에서 암호화를 처리하기 때문에 애플리케이션 성능에 영향을 주지 않습니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 create_volume()으로 새 EBS 볼륨을 생성합니다.
Encrypted=True로 설정하면 암호화가 활성화됩니다. KmsKeyId에 CMK를 지정하면 해당 키로 암호화됩니다.
더 좋은 방법은 enable_ebs_encryption_by_default()로 계정 수준에서 기본 암호화를 활성화하는 것입니다. 이렇게 하면 새로 생성되는 모든 볼륨이 자동으로 암호화됩니다.
개발자가 실수로 암호화를 빼먹는 일이 없어집니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 전자상거래 플랫폼의 데이터베이스 서버를 운영한다고 가정해봅시다. MySQL 데이터베이스는 고객의 주문 정보, 결제 정보를 디스크에 저장합니다.
EBS 볼륨을 암호화하면 이 모든 데이터가 디스크 수준에서 보호됩니다. 만약 서버를 교체하거나 볼륨을 삭제할 때도 데이터 유출 걱정이 없습니다.
스냅샷을 다른 리전으로 복사할 때도 암호화 상태가 유지됩니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 기존 암호화되지 않은 볼륨을 직접 암호화할 수 있다고 생각하는 것입니다. 안타깝게도 기존 볼륨은 암호화 상태를 변경할 수 없습니다.
따라서 암호화되지 않은 볼륨의 스냅샷을 생성하고, 그 스냅샷을 암호화 옵션으로 복사한 다음, 새 암호화 볼륨을 생성하는 마이그레이션 과정이 필요합니다. EBS 암호화는 인스턴스와 볼륨 간 전송 데이터도 암호화합니다.
디스크에 저장될 때뿐만 아니라 EC2와 EBS 스토리지 간에 데이터가 이동할 때도 암호화된 채로 전송됩니다. 이를 전송 중 암호화(encryption in transit)라고 합니다.
저장 시 암호화(encryption at rest)와 함께 완전한 데이터 보호를 제공합니다. 루트 볼륨 암호화도 가능합니다.
EC2 인스턴스를 시작할 때 루트 볼륨 암호화 옵션을 선택하면 운영체제가 설치된 디스크도 암호화됩니다. 부팅 과정에서 자동으로 복호화되므로 사용자는 아무것도 신경 쓸 필요가 없습니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 데이터베이스 서버의 EBS 볼륨을 암호화한 김개발 씨는 안심할 수 있게 되었습니다.
"디스크까지 암호화하니 정말 든든하네요!" EBS 암호화는 서버 보안의 기본입니다. 한 번 설정해두면 투명하게 작동하므로 애플리케이션에 아무런 영향을 주지 않으면서도 강력한 보안을 제공합니다.
여러분도 오늘 배운 내용을 바탕으로 모든 EBS 볼륨에 암호화를 적용해 보세요.
실전 팁
💡 - 계정의 모든 리전에서 EBS 기본 암호화를 활성화하는 것이 좋습니다. 스크립트로 일괄 설정할 수 있습니다
- 암호화된 볼륨의 스냅샷을 다른 계정과 공유할 때는 CMK 권한도 함께 공유해야 합니다
- gp3 볼륨 타입을 사용하면 암호화 성능이 더욱 향상됩니다
6. 봉투 암호화 개념
모든 암호화를 성공적으로 적용한 김개발 씨는 뿌듯했습니다. 그런데 박시니어 씨가 물었습니다.
"그런데 KMS가 실제로 어떻게 암호화하는지 알아?" 김개발 씨는 멈칫했습니다. "음...
CMK로 데이터를 암호화하는 거 아닌가요?" 박시니어 씨가 고개를 저었습니다. "아니야, 봉투 암호화라는 게 있어."
봉투 암호화는 데이터를 암호화하는 키를 다시 암호화하는 이중 암호화 방식입니다. 마치 편지를 봉투에 넣고, 그 봉투를 다시 큰 봉투에 넣는 것과 같습니다.
CMK는 데이터 키를 암호화하고, 데이터 키는 실제 데이터를 암호화합니다. 이 방식으로 대용량 데이터도 빠르고 안전하게 암호화할 수 있습니다.
다음 코드를 살펴봅시다.
import boto3
import base64
kms = boto3.client('kms')
# 데이터 키 생성 (봉투 암호화의 핵심)
response = kms.generate_data_key(
KeyId='alias/customer-data-key', # CMK로 데이터 키를 암호화
KeySpec='AES_256' # 256비트 AES 키 생성
)
# 평문 데이터 키 (실제 데이터 암호화에 사용)
plaintext_key = response['Plaintext']
# 암호화된 데이터 키 (CMK로 암호화됨, 데이터와 함께 저장)
encrypted_key = response['CiphertextBlob']
# 실제 데이터를 데이터 키로 암호화 (로컬에서 수행)
from cryptography.fernet import Fernet
cipher = Fernet(base64.urlsafe_b64encode(plaintext_key[:32]))
encrypted_data = cipher.encrypt(b"민감한 고객 데이터")
# 평문 키는 메모리에서 즉시 삭제
del plaintext_key
# 암호화된 데이터와 암호화된 키를 함께 저장
print(f"암호화된 데이터: {encrypted_data}")
print(f"암호화된 키: {base64.b64encode(encrypted_key)}")
박시니어 씨가 화이트보드에 그림을 그리기 시작했습니다. "자, 봉투 암호화를 이해하려면 먼저 왜 이런 방식이 필요한지 알아야 해." 그렇다면 봉투 암호화란 정확히 무엇일까요?
쉽게 비유하자면, 봉투 암호화는 마치 이중 봉투 시스템과 같습니다. 중요한 편지를 작은 봉투에 넣고 봉인합니다.
그런 다음 그 작은 봉투를 큰 봉투에 넣고 다시 봉인합니다. 도둑이 큰 봉투를 열어도 작은 봉투가 또 봉인되어 있어서 쉽게 내용을 볼 수 없습니다.
이처럼 봉투 암호화도 데이터를 한 번 암호화하고, 그 암호화 키를 다시 암호화하는 이중 보안을 제공합니다. 봉투 암호화 없이 CMK로 직접 데이터를 암호화하면 어떤 문제가 있을까요?
KMS는 암호화할 수 있는 데이터 크기에 제한이 있습니다. 한 번에 최대 4KB까지만 암호화할 수 있습니다.
기가바이트 단위의 파일을 암호화하려면 수천 번 KMS를 호출해야 하는데, 이는 비용도 많이 들고 속도도 느립니다. 또한 네트워크를 통해 대용량 데이터를 KMS로 전송하는 것도 보안 위험이 될 수 있습니다.
바로 이런 문제를 해결하기 위해 봉투 암호화 방식을 사용합니다. 봉투 암호화를 사용하면 대용량 데이터를 로컬에서 빠르게 암호화할 수 있습니다.
KMS는 작은 데이터 키만 암호화하므로 한 번의 API 호출로 충분합니다. 암호화된 데이터 키는 암호화된 데이터와 함께 저장하면 됩니다.
복호화할 때도 KMS에 암호화된 데이터 키만 보내면 평문 데이터 키를 받아올 수 있습니다. 무엇보다 실제 데이터는 절대 KMS로 전송되지 않는다는 큰 이점이 있습니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 generate_data_key()를 호출하여 새 데이터 키를 생성합니다.
이 메서드는 두 가지를 반환합니다. Plaintext는 실제 데이터를 암호화할 때 사용할 평문 데이터 키이고, CiphertextBlob은 CMK로 암호화된 데이터 키입니다.
평문 데이터 키로 실제 데이터를 로컬에서 암호화합니다. 암호화가 끝나면 평문 데이터 키는 즉시 메모리에서 삭제합니다.
암호화된 데이터와 암호화된 데이터 키를 함께 저장합니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 동영상 스트리밍 서비스를 개발한다고 가정해봅시다. 사용자가 업로드한 동영상 파일은 수 기가바이트에 달합니다.
봉투 암호화를 사용하면 서버에서 데이터 키를 생성하고, 그 키로 동영상 파일 전체를 로컬에서 암호화합니다. KMS는 단 한 번만 호출하여 데이터 키를 생성하고 암호화합니다.
암호화된 동영상과 암호화된 데이터 키를 S3에 함께 저장합니다. 나중에 동영상을 재생할 때는 암호화된 데이터 키만 KMS로 보내 복호화하고, 받은 평문 데이터 키로 동영상을 복호화합니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 평문 데이터 키를 디스크에 저장하는 것입니다.
평문 데이터 키는 절대 저장하면 안 됩니다. 메모리에서만 사용하고 즉시 삭제해야 합니다.
저장해야 하는 것은 암호화된 데이터 키입니다. 또한 같은 데이터 키를 여러 파일에 재사용하지 말고, 파일마다 새로운 데이터 키를 생성하는 것이 올바른 방법입니다.
봉투 암호화의 복호화 과정도 이해해야 합니다. 암호화된 데이터를 읽을 때는 먼저 저장된 암호화된 데이터 키를 KMS의 decrypt() 메서드로 보냅니다.
KMS는 CMK를 사용하여 데이터 키를 복호화하고 평문 데이터 키를 반환합니다. 이 평문 데이터 키로 실제 데이터를 복호화합니다.
복호화가 끝나면 평문 데이터 키를 즉시 메모리에서 삭제합니다. AWS 서비스들은 대부분 내부적으로 봉투 암호화를 사용합니다.
S3가 객체를 암호화할 때, EBS가 볼륨을 암호화할 때, RDS가 데이터베이스를 암호화할 때 모두 봉투 암호화 방식을 사용합니다. 사용자는 이 과정을 전혀 보지 못하지만, 뒤에서는 데이터 키가 생성되고 CMK로 암호화되는 작업이 일어나고 있습니다.
봉투 암호화는 성능과 보안의 균형을 맞춘 훌륭한 설계입니다. 대칭키 암호화의 빠른 속도와 KMS의 강력한 키 관리 기능을 모두 활용할 수 있습니다.
데이터 키는 로컬에서 빠르게 암호화를 수행하고, CMK는 안전하게 키를 보호합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
봉투 암호화의 원리를 이해한 김개발 씨는 감탄했습니다. "아, 그래서 S3나 EBS가 대용량 데이터도 빠르게 암호화할 수 있었군요!" 봉투 암호화는 클라우드 암호화의 핵심 원리입니다.
이 개념을 제대로 이해하면 KMS를 더 효과적으로 활용할 수 있고, 직접 암호화 시스템을 구현할 때도 올바른 설계를 할 수 있습니다. 여러분도 오늘 배운 내용을 바탕으로 안전하고 효율적인 암호화 시스템을 구축해 보세요.
실전 팁
💡 - generate_data_key_without_plaintext()를 사용하면 평문 데이터 키 없이 암호화된 키만 받을 수 있어 더 안전합니다
- 데이터 키는 가능한 한 자주 교체하세요. 같은 키로 너무 많은 데이터를 암호화하면 보안이 약해집니다
- 암호화 라이브러리는 검증된 것을 사용하세요. AWS Encryption SDK는 봉투 암호화를 자동으로 처리해줍니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Helm 마이크로서비스 패키징 완벽 가이드
Kubernetes 환경에서 마이크로서비스를 효율적으로 패키징하고 배포하는 Helm의 핵심 기능을 실무 중심으로 학습합니다. Chart 생성부터 릴리스 관리까지 체계적으로 다룹니다.
보안 아키텍처 구성 완벽 가이드
프로젝트의 보안을 처음부터 설계하는 방법을 배웁니다. AWS 환경에서 VPC부터 WAF, 암호화, 접근 제어까지 실무에서 바로 적용할 수 있는 보안 아키텍처를 단계별로 구성해봅니다.
AWS Organizations 완벽 가이드
여러 AWS 계정을 체계적으로 관리하고 통합 결제와 보안 정책을 적용하는 방법을 실무 스토리로 쉽게 배워봅니다. 초보 개발자도 바로 이해할 수 있는 친절한 설명과 실전 예제를 제공합니다.
AWS Secrets Manager 완벽 가이드
AWS에서 데이터베이스 비밀번호, API 키 등 민감한 정보를 안전하게 관리하는 Secrets Manager의 핵심 개념과 실무 활용법을 배워봅니다. 초급 개발자도 쉽게 따라할 수 있도록 실전 예제와 함께 설명합니다.
AWS WAF 웹 방화벽 완벽 가이드
웹 애플리케이션을 악의적인 공격으로부터 보호하는 AWS WAF의 핵심 개념과 실무 활용법을 초급 개발자도 쉽게 이해할 수 있도록 풀어낸 가이드입니다. SQL Injection, XSS 공격 방어부터 속도 제한까지 실전 예제로 배웁니다.