Cloud/AWS

AWS KMS

NOG 2024. 12. 13. 23:49

※ 개인적으로 공부하면서 정리한 글이며 틀린 내용 있다면 알려주시면 감사합니다.
 

 

KMS (Key Management Service)

 
그림출처 : https://docs.aws.amazon.com/ko_kr/kms/latest/developerguide/overview.html
 
테이터를 암호화할 때 쓰이는 암호화 키 A 를 보호해야 한다.
A 키를 암호화하는 경우 A키를 암호화한 키 B 를 보호해야 한다.
KMS는 최상위 레벨의 암호화 키(루트키)를 보호한다.
 
KMS는 데이터를 암호화할때 사용되는 Key에 대한 전체적인 관리 (생성, 활용, 보관, 무효화, 삭제 등)를 담당한다.
암호화 Key의 클라우드 서비스를 통해 중앙 집중식으로 관리
 

 

KMS 특징

 
 
-중앙집중식 제어
KMS 키의 수명 주기와 권한을 중앙집중식으로 제어할 수 있다.
 
-AWS 서비스들과 연계
S3, EBS, RDS, RedShift 등 암호화 대상 서비스와 연동하여 사용
KMS 키를 이용해 데이터를 암호화 저장하거나 서명/인증 등의 프로세스에 적용
 
-감사 모니터링
CloudTrail을 통해 KMS에 대한 모든 요청들(언제 어떤 서비스에서 키가 사용되었는지)을 로깅,
CloudTrail에 연동된 S3 버킷으로 저장
 
-보안규정 준수
국가 별로 지정되어있는 규정 준수 체제의 인증과 검증을 받고 운영 ( 국내 인증인 K-ISMS)도 포함
 
 

특성 AWS KMS AWS CloudHSM
관리 주체 AWS 측에서 HSM 하드웨어를 관리. 사용자가 HSM 하드웨어를 제공 받아 직접 관리
사용자 접근성 사용자는 키 자료에 접근 불가.
CLI/SDK 등을 통하거나 AWS 서비스로 호출
사용자가 키 자료에 직접 접근 및 관리 가능
( 더 높은 수준의 커스터마이징)
보안 인증 FIPS 140-2 Level 2 FIPS 140-2 Level 3 ( 더 강력한 보안)
키 관리 AWS에서 자동 로테이션, 생성, 삭제 지원. 키의 생성, 삭제, 저장을 사용자가 직접 처리.
서비스 연동 S3, RDS, EBS 등 주요 AWS서비스와 연동 KMS를 거쳐 AWS서비스와 연동
애플리케이션 수준에서 통합 구현 필요.
공유 구조 여러 계정에서 HSM 하드웨어 공유한다. HSM 하드웨어를 특정 계정에서 독점적 사용

 
 /*
HSM은 암호화 키를 생성하고 보호하며, 암호화/복호화 작업을 수행하는 전용 보안 하드웨어 장치
KMS는 이 하드웨어를 사용해서 키를 생성하고 관리한다.
소프트웨어적으로 파티션을 나누어 논리적 분리가 되어있을 뿐  물리적으로 격리되어 있지는 않다.
 
KMS는 키 자료가 HSM 장치 내부에서만 사용되도록 설계되어있어 CLI/SDK등을 통해 API 호출
API 호출 예시)
-Encrypt: 데이터를 암호화

-Decrypt: 데이터를 복호화
-GenerateDataKey: 데이터를 암호화하기 위한 데이터 키(Data Key)를 생성
-ReEncrypt: 암호화된 데이터를 다른 키로 다시 암호화
*/
 
 

봉투암호화 ( Envelope Encryption )

 
공식문서에 봉투 암호화는 데이터 키로 일반 텍스트 데이터를 암호화한 후, 다른 키 아래에서 데이터 키를 암호화하는 방법이라고 설명되어있다.
 
https://docs.aws.amazon.com/ko_kr/kms/latest/developerguide/kms-cryptography.html

 
먼저 KMS에서 CMK ( Customer Master Key )를 생성한다. CMK는 직접 암호화/복호화할 수 있지만 위 그림에서는 Data Key를 생성하는 역할을 한다.
 
1. GenerateDataKey API를 호출하면 CMK는 데이터를 암/복호화하는 데 사용할 Plaintext Data Key (파란색)과이 파란색 키를 암호화한 Encrypted data key(빨간색)를 준다.
 
2. 평문키(파란색)를 활용해서 특정 데이터를 암호화 알고리즘을 통해 암호화된 데이터를 추출한다.
 
3. 평문 Data Key는 메모리에서 삭제되고 암호화된 데이터암호화된 키(빨간색 키)를 저장소(S3,RDS,DynamoDB 등)에 저장한다.
 
4. KMS는 CMK를 사용하여 암호화된 Data key(빨간색 키)를 복호화하여  평문키로 만들어 암호화된 데이터를 복호화한다. 
 
 
이렇게 저장소에 평문키가 아닌 암호화된 데이터(Encrypted data)암호화된 키(빨간색 키)를 저장하는 방식 을 '봉투 암호화'라고 한다.
 
=>해커가 저장소를 해킹해도 암호화된 데이터 및 키만 존재하므로 상대적으로 안전하다.
 
 
 

Key 유형

 

 

① AWS Managed Key ( AWS 관리형 키)

 

AWS 서비스에서 사용하기 위해 생성/관리하는 키
 
-이 키를 통해 AWS 서비스들이 KMS 키를 자동으로 사용하게된다.
-AWS Managed Key는 키 내용과 정책을 보거나 사용내역 로깅은 가능, 수정 불가능
-교체(로테이션) /삭제 등의 제어는 할 수 없다. 본인이 제어하고 싶을 때 제어하지 못한다.
-AWS Managed Key는 매년 자동으로 교체된다.

 

 

SSE-KMS AWS 관리형 Key 선택하는 모습 ( 기본적으로 선택할 수 있는 키)


 
/*
AWS 서비스(S3, RDS, EBS 등)에서 암호화 옵션을 활성화하면 키가 생성됨
*/

 

② Customer Managed Key  (고객 관리형 키)

 

사용자가 직접 계정에 Key를 생성/관리할 수 있는 키
 
-생성한 키에 대한 완전한 제어 권한을 갖는다.
-키 사용정책 / IAM 정책/ 활성, 비활성화/ 태그 /로테이션 설정 등 모두 가능
-Customer Managed Key 지원하지 않는 않는 서비스가 있다.

 

SSE-KMS 고객 관리형 Key 선택하는 모습 ( 직접 생성한 키)


 
/*
콘솔에서 키 생성하면 만들어지는 것이 customer managed key 이며 CLI 또는 SDK로도 생성가능
*/
 

③ AWS Owned Key 

 

여러 계정에서 AWS 서비스가 사용하는 키 ( 본인에게 종속되지 않아 다른 계정에도 활용)
 
- 따라서 사용자는 Owned Key에 대해 어떠한 권한도 가지지 못한다. ( 속성 조회,설정 및 로테이션 설정 불가능)
- 비용 무료

 

/*

AWS 서비스에서 키를 활용해 리소스를 보호하는데 사용한다.
DynamoDB 기본 암호화 방식에 사용되는 것처럼  AWS 내부에서 사용되어 일반적으로 CMK에 포함되지 않는다.

*/

 
 

Customer Managed Key  소개

 

 

① Key 사용 케이스

 
1. 대칭키로 사용
 
1-1 KMS 키(CMK)를 직접 사용해서 암호화/복호화
이 경우 키 다운로드 불가능 => 암/복호화 작업은 KMS에서만 가능
 
KMS가 암/복호화 작업을 요청하게 하기 싫을 경우 Data Key를 사용
이 경우는 키를 다운로드 가능 => 암/복호화 작업이 애플리케이션에서 일어나 API 호출 최소화, 대량 데이터 처리 가능
Data key는  KMS는 CMK로부터 임시로 Data key를 생성한다. 그리고 애플리케이션이 이것을 사용하여 데이터를 암호화/복호화 이후 평문 형태는 삭제된다.
 
1-2 HMAC KMS keys : hash 기반 메세지 인증 등에 활용
 
 
2. 비대칭키로 사용
 
암/복호화, 디지털 서명/검증 등 활용 가능하다.
 
 
 

② Key material  (키 구성요소)  4가지 제공 방법

 

그림출처 : https://docs.aws.amazon.com/ko_kr/kms/latest/developerguide/importing-keys.html
 
KMS key는 key material과 메타데이터(Key ID, 상태(enable/disable), 생성 시간,  용도, 알고리즘 등) 으로 구성되어 있다.
핵심적인 요소인 key material은 데이터를 암호화하거나 복호화하는 데 사용하는 데이터 비트를 나타내는 값을 말한다.
참고로 CMK의 Key material은 암호화 되지 않은 상태로 가져와지지 않는다.
 
4가지 제공방식은 아래와 같다.
 
1. AWS KMS가 생성
 
2. 외부에서 생성한 key material을 KMS에서 Import
 
3. AWS CloudHSM을 통한 생성
 
4. 외부 시스템에서 키 생성,저장,관리하고 KMS는 암호화 작업만 잔행
 
 
 

③ Region Key 분류

 
- 단일 리전 키 : 하나의 리전에서만 생성 및 사용
(타 리전에서 쓰기 위해 크로스 리전=키가 복제되지 않고 원본 리전에서 작업이 수행되는 방식도 있다. )
 
 

그림 출처: https://docs.amazonaws.cn/en_us/kms/latest/developerguide/mrk-how-it-works.html
 
 
- 다중 리전 키 (mrk) : 여러 리전에서 동일한 키를 가지고 있는 것
리전 간 키를 복제하여 각 리전에서 독립적으로 작업을 수행할 수 있다.
모든 복제본이 동일한 키 ID와 키 구성요소를 공유한다.
 
 
이후 키를 사용하는 사람, 관리하는 사람, 다른 AWS 계정에 권한 등 을 부여할 수 있다.
 
 

키 정책 및 로테이션

 

 
키 별로 부여되는 리전 단위 정책으로 KMS Key의 사용 권한을 부여 
IAM 권한  및 키 정책에  둘 다 권한 있어야 키를 사용가능하다.
키 정책 대신 특정 조건에 따라 제한적으로 설정하는 임시 티켓인 grants를 사용하기도 한다.
 

이외에도 교체기간 등을 설정하여 자동으로 키 교체 하도록 설정할 수 있다.
 
 
 

KMS SDK 예시

 
아래는 블로그에서 가져온 KMS를 이용해 데이터를 암호화/복호화 하는 Python 예제이다. 
KMS 에 접근하여 CMK 를 통해 data key 생성하는 부분은 AWS 의 python SDK인 boto3를 이용하였으며,
data key를 이용한 데이터 암호화는 대칭키 암호화 방식인 AES 를 활용하였다.
 
출처: https://bluese05.tistory.com/71 [ㅍㅍㅋㄷ:티스토리]
 

import boto3
import base64
from Crypto.Cipher import AES

BLOCK_SIZE = 32
PADDING = '|'

key_arn = '{{ KMS_ARN }}'
message = 'This is test for KMS. written by JHSong'

#boto3 라이브러리를 사용하여 AWS KMS와 통신할 클라이언트 생성
client = boto3.client('kms')

#AWS 사용하여 데이터 암호화에 사용할 Data Key 생성
data_key = client.generate_data_key(
    KeyId=key_arn,
    KeySpec='AES_256'
)

pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING

# KMS로부터 반환된 응답에서 평문 키(Plaintext)와 암호화된 키(Ciphertext)를 추출합니다.
plaintext_key = data_key.get('Plaintext')
encrypted_key = data_key.get('CiphertextBlob')

# AES 암호화 객체를 생성하고 객체를 사용하여 메세지를 암호화한 후 Base64로 인코딩합니다.
###### Encrypted data ######## 
encryptor = AES.new(plaintext_key)
encrypted_data = base64.b64encode(encryptor.encrypt(pad(message)))

print("########## Encrypted Data ##############")
print(encrypted_data)

# 암호화된 데이터 키를 복호화하여 평문 데이터 키를 얻고 AES 복호화 객체를 생성합니다.
###### Decrypted data ######## 
decrypted_key = client.decrypt(CiphertextBlob=encrypted_key).get('Plaintext')
decryptor = AES.new(decrypted_key)

# Base64 e디코딩하고 객체를 사용하여 복호화하여 원본 메시지를 복원합니다.
decrypted_str = decryptor.decrypt(base64.b64decode(encrypted_data)).decode('utf-8')

print("########## Decrypted Data ##############")
print(decrypted_str.rstrip(PADDING))

 
 
Data key를 생성하고 평문키와 암호화된 키를 추출 후 암호화된 데이터를 출력하고
암호화된 키를 복호화하여 평문키로 만들고 원본메세지를 복원하는 과정을 보여주는 코드다.
 
해당 블로그의 코드에서 일부 수정하여서  암호화된 데이터와 복호화된 데이터를 뽑아낼 수 있었다.

 
 
 
 

KMS 와 Secrets Manager

 

 
Secrets Manager는 데이터베이스 등에 접근할 때 사용하는 Secret(로그인 시 인증 정보 등의 비밀값)을 관리하는 서비스
비밀 값들을 AWS Secrets Manager에 저장해두고 어플리케이션 AWS API를 호출해서 받아서 사용
 
 
예를 들면, 애플리케이션에서 RDS에 접근할 때, Secrets Manager에서 Secret(로그인 정보)을 가져와서 인증할 수 있다.
즉, 이를 통해 로그인 정보를 애플리케이션에 직접 입력하는 하드코딩을 할 필요가 없어진다.
또한, Secret은 정기적으로 갱신(회전)되며, 버전 관리도 이루어진다.
 
 

 
KMS와 Secrets Manager를 연동하면 Secret을 보호하기 위해 Data key가 사용된다.
로테이션이 이루어질 때마다 Data key도 새롭게 자동으로 생성되므로, 높은 보안 수준의 인증을 구현할 수 있다.

 

def get_secret():

    secret_name = "aws-managed-secrets"
    region_name = "us-east-1"

    # Create a Secrets Manager client
    session = boto3.session.Session()
    client = session.client(
        service_name='secretsmanager',
        region_name=region_name
    )

    try:
        get_secret_value_response = client.get_secret_value(
            SecretId=secret_name
        )
    except ClientError as e:
        # For a list of exceptions thrown, see
        # https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
        raise e

    secret = get_secret_value_response['SecretString']
    print(secret)

 
시크릿 값을 불러올 수 있는 코드도 기본으로 제공하고 있다.

 

 


 
참고
https://bluese05.tistory.com/71
https://www.youtube.com/watch?v=4k3FvmYF37E
https://docs.aws.amazon.com/ko_kr/code-library/latest/ug/python_3_secrets-manager_code_examples.html
https://happy-jjang-a.tistory.com/105
https://trippy-sanfran.tistory.com/66
https://jibinary.tistory.com/248
https://blog.omoknooni.me/94#KMS%20%EB%8F%99%EC%9E%91%20%EA%B3%BC%EC%A0%95-1

'Cloud > AWS' 카테고리의 다른 글

AWS WAF (Web Application Firewall)  (0) 2024.12.05
S3 vs EBS vs EFS  (0) 2024.11.25
VPC Endpoints & VPC  (0) 2024.11.23
Autoscaling Group & ALB  (0) 2024.11.20
IAM User가 아닌 EC2에 역할 부여  (0) 2024.11.20