본문 바로가기
AWS/KMS

AWS KMS 개념과 응용 - 1

by 알파해커 2022. 10. 13.
반응형

이 글에서는 AWS KMS의 기본 개념에 대해서 알아본다.

바로 응용편 부터 보고싶다면 "AWS KMS 개념과 응용 - 2"를 보자.

 


1. 배경

암호화를 적용하는 개발자들은 항상 두 가지 문제를 신경써야 한다.

  • 데이터를 암호화 하는데, 어떻게 정확하게 키를 생성하고 사용할 것인가.
  • 사용 후, 키를 안전하게 보호하는 방법은 무엇인가.

첫 번째의 경우 제공되는 SDK 등을 통해서 해결이 가능하다.

두 번째의 경우 다음과 같은 조건으로 관리될 수 있어야 한다.

 

(1) 데이터를 암호화한 키가 노출되지 않도록 해야 한다.
이 때, 데이터를 암호화한 키는 데이터베이스에 저장하지 말아야 한다.
그리고 복호화는 할 수 있어야 하므로, 복호화 할 수 있는 키는 어딘가에 보관해야 한다.

 

(2) 최악의 경우 복호화 관련 키 정보가 노출되더라도, 의도되지 않은 상황에서 데이터가 복호화 될 수 없도록 원천 봉쇄할 방법이 필요하다. 100% 보안은 존재할 수 없으니, 항상 최악의 상황을 가정하고 대응할 수 있는 시스템이 필요하다.

 

AWS KMS는 이런 것들이 가능한 서비스이다.

 


2. 암/복호화

2.1 KMS Key

KMS Key는 다음과 같이 크게 세가지로 나눌 수 있다: CMK(Customer Managed Key), AWS Managed Key, AWS Owned Key.

 

 

AWS Managed Key, AWS Owned Key는 AWS 서비스(ex: DynamoDB, S3 등)에서 리소스를 보호하기 위한 목적으로 있는 것이다.

 

이 둘 Key의 공통점은 사용자가 Key를 생성하거나 관리할 수 없다는 것이다. 따라서 사용자가 직접 Key를 제어하려는 목적이 없는 경우에는 간편하게 사용할 수 있는 옵션이라고 생각할 수 있다.

 

둘의 차이점은 Key의 사용 범위에 있다. AWS Managed Key의 경우 사용자의 계정에서 관리 되는 것이며, 따라서 계정 내에서만 사용된다. 그리고 계정 내에서 Key Policy를 확인하고, CloudTrail 로그를 통해 Audit을 할 수 있다. AWS Owned Key의 경우 DynamoDB나 S3와 같은 AWS 서비스에서 관리하고 사용되는 것으로 계정 내에서 Key Policy를 확인하거나 Key 사용에 대한 Audit이 불가능하지만, 간편하게 적용할 수 있고 (대부분) 사용 요금이 발생하지 않는다는 장점이 있다.

 

가장 많이 사용되는 Key는 CMK(Customer Managed Key)이다. CMK는 사용자가 계정에서 직접 생성, 관리, 감사(Audit)이 가능하다.

 

CMK를 이용해서 KMS 내에서 직접 암/복호화도 가능하지만, 이 경우 암호화 하려는 데이터의 사이즈가 4KB 제한되는 등의 제약 사항이 있고, 암/복호화를 할 때마다 매번 KMS를 호출해야 하기 때문에 성능+비용 측면에서 손해가 있다. 따라서 대용량 데이터를 암호화 하는 경우 CMK를 바로 이용하지 않고, Data Key라는 것을 이용한다.

 

실제로 데이터를 암호화 하는데 사용되는 Key는 Data Key이며, 이 Data Key를 핸들링하기 위한 Key로 CMK를 사용한다. 이렇게 Data Key를 제어하는 Key를 Master Key라고 부른다.

 

Master Key를 이용해서 Data Key를 암/복호화하고, Data Key를 이용하여 데이터를 암/복호화하는 계층형 구조로 되어 있다. 데이터를 암호화 하기 위해 KMS에 Data Key를 요청하면, KMS는 평문 Data Key와 암호화된 Data Key를 준다.

 

 

각 Key에 대한 특징은 다음과 같다.

 

(1) Master Key

Region별로 생성 가능하며 AWS에 의해 보관 관리되고 키 값이 노출되지 않는다. 어플리케이션에서는 암/복호화를 위해 KEY ID값을 받급 받아 사용한다. 해당 Key를 이용해서 직접 암/복호화 가능하지만 데이터 사이즈 제한이 있고, 주로 Data Key를 암호화 하는데 사용된다.

 

(2) 평문 Data key

KMS에 의해 발급되며 암/복호화 시 꼭 필요한 Key 값 이지만, 해당 시점에만 사용하고 절대 별도로 보관해서는 안된다.

즉, 보안을 위해 암/복호화 직후 폐기 처리 해야한다.

 

(3) 암호화된 Data key

평문 Data Key를 Master Key로 암호화한 것으로, 복호화 시 평문 Data Key를 얻기 위해 사용한다.

암호화 된 데이터를 복호화 하기 위해서는 평문 Data Key가 필요한데, 이 평문 Data Key를 얻기 위해서는 Master Key가 필요하기 때문에, Master Key로 데이터를 암/복호화 하는 과정을 제어할 수 있게 되는 것이다.

 

 

2.2 암/복호화 과정

2.2.1 암호화

아래 그림은 AWS KMS 클라이언트를 통한 평문 암호화 동작을 그림으로 나타낸 것이다. 

KMS에서 제공하는 GenerateDataKey 라는 인터페이스를 통해 평문을 봉투 암호화 할 수 있다.

 

 

1. KMS에 암호화를 위한 Data Key를 요청하면, KMS는 암호화를 위한 Data Key키와, 이 Data Key를 Master Key를 이용해 암호화 한 Encrypted Key(암호화 된 Data Key)를 돌려준다.

2. 평문은 Data Key를 이용해 암호화 알고리즘에 보내진다.

3. 암호화된 데이터가 만들어지며, 이 때 Data Key는 즉시 폐기해야 한다. 그리고 암호화된 데이터는 암호화된 Data Key(Encrypted Key)와 함께 보관한다.

 

2.2.2 복호화

아래 그림은 AWS KMS 클라이언트를 통한 암호문 복호화 동작을 그림으로 나타낸 것이다. 

KMS에서 제공하는 봉투 암호화를 사용했다면, 암호화 시 사용하였던 Data Key를 요청하여 데이터를 복호화할 수 있다.

 

 

1. KMS에 암호화된 Data Key를 복호화하는 요청을 보낸다.

2. KMS는 Master Key를 이용하여, 암호화된 Data Key를 복호화해서 돌려준다. 즉, Data Key를 돌려준다.

3. 암호화할 때 사용했던 Data Key를 이용해 암호화된 데이터를 복호화한다.

 

 

2.3 봉투암호화

봉투암호화는 데이터를 암호화하는데 사용하는 Key(Data Key)를 암호화된 데이터와 함께 보관하는 방식을 말한다. 이 때 Key는 Master Key로 암호화 된다.

 

데이터를 암호화하는 과정에서는 데이터를 보호하는 만큼 Key를 보호하는 것도 중요하며, 어떻게 보관할지도 고민 포인트이다.

 

봉투암호화 방식에서는 Key를 Master Key로 암호화함으로써 안전하게 보호될 수 있고, 필요에 따라 Key를 비활성화 시킬 수도 있어서 관리 측면에서 효용이 늘어난다.

 

또한, 이미 안전한 방식으로 Key가 암호화 되어있고, 이를 암호화된 데이터와 함께 보관하기 때문에 별도의 보관 장소를 마련해야 하는 부담도 줄어든다.

 

 

이 방식은 결과적으로, (Data Key를 대칭키로 사용한다고 가정했을때) 암/복호화의 속도가 빠르다는 대칭키의 장점과 키 관리가 용이하다는 비대칭키의 장점을 모두 가지고 있게 된다. 그렇기 때문에 특히 대용량 데이터를 암호화할 때 유리하다고 볼 수 있다.

 

 

2.4 암호 문맥 (Encrypt context)

암/복호화에 정확하게 동작하는 것을 보장하기 위한 절차로 동일한 정보가 확인된 경우에만 해당 키에 대한 작업을 허용하는 것이다.

 

암호화와 관련된 부가정보를 추가하는 것으로, 그 부가정보까지 정확하게 입력되어야만 정상적으로 암/복호화가 이루어지고. 그렇지 않으면 암/복호화를 거부한다.

 

 

위의 왼쪽 이미지를 보자. Share.TXT라는 평문 파일의 내용을 Data Key를 이용해 암호화 한 것이 Secret.TXT이라고 해보자. 만약에 Secret.TXT의 파일명을 Share.TXT로 바꾸고, Data Key를 이용해 복호화 하면 복호화에 성공하게 된다. 

 

그런데 오른쪽 이미지처럼, Encryption Context로 파일명을 설정해놓는다면, 이름이 변경된 파일을 복호화 할 때 Encryption Context 설정에 위반되기 때문에 복호화가 되지 않는다.

 

 

2.5 암호화 알고리즘

2.5.1 알고리즘

지원하는 암/복호화 알고리즘과 각 알고리즘 별 데이터 사이즈 제한은 다음과 같다.

 

Symmetric encryption KMS keys

  • SYMMETRIC_DEFAULT(AES-GCM): 4096 bytes

RSA_2048

  • RSAES_OAEP_SHA_1: 214 bytes
  • RSAES_OAEP_SHA_256: 190 bytes

RSA_3072

  • RSAES_OAEP_SHA_1: 342 bytes
  • RSAES_OAEP_SHA_256: 318 bytes

RSA_4096

  • RSAES_OAEP_SHA_1: 470 bytes
  • RSAES_OAEP_SHA_256: 446 bytes

SM2PKE: 1024 bytes (China Regions only)

 

 

2.5.2 알고리즘 조합

KMS에서는 단순히 AES-GCM 같은 암호화 알고리즘만 사용하지 않고, Key Derivation, Signinig, Key Commitment 함께 사용하는 것을 권장하고, AWS에서 제공하는 Encryption SDK에서도 그것이 디폴드로 적용되어 있다.

그러나 성능상의 이유로 Key Derivation, Signinig, Key Commitment 빼고 /복호화를 진행하는 것도 지원한다 (권장하지 않는 방식).

 


3. 정책

KMS Key에 대한 접근 제어는 Key Policy, IAM Policy, Grant를 통해 가능하다.

KMS에서 마스터 키(CMK)를 다루는 방법은 크게 세가지 유형 중 하나이다.

  • Key Policy만 사용
  • Key Policy와 IAM Policy을 함께 사용(권장)
  • Key Policy와 Grant를 사용(권장)

Key Policy를 통해서 사용 주체와 권한의 범위를 정하고, IAM Policy를 통해서 좀 더 세분화된 제어가 가능하도록 한다.

Policy는 명시적인 Allow여야 하며, 명시적인 Deny가 명시적인 Allow보다 더 우선한다. 또한 암묵적인 Deny가 적용된다.

 

3.1 Key Policy

Key Policy는 개별 키별로 정의하는 Resource-based policy이다. 이를 통해 누가(Principal), 어떤 것(Action)을 할 수 있는지 결정한다. 또, Key 접근 제어 정책을 설정할 때 IAM Policy를 함께 사용할 수 있는데, 그렇게 하기 위해서는 Key Policy에서, IAM Policy를 함께 사용한다는 내용이 명시되어야 한다.

 

Key Policy 예시

아래 Key Policy의 STATEMENT-1 이 Key 접근 제어를 위해 IAM Policy를 함께 사용하겠다는 것을 명시하는 내용이다.

STATEMENT-2는 KMS Key를 관리하는 User와 Role에게 관리 권한(Key 생성, 활/비활성화, 삭제 등)을 부여하는 것이고, STATEMENT-3는 KMS Key를 사용하는 User와 Role에게 사용 권한(암/복호화, DataKey 생성 등)을 부여하는 것이다.

 

{

  "Version": "2012-10-17",

  "Id": "key-consolepolicy-2",

  "Statement": [

    /* STATEMENT-1 */

    {

      "Sid": "Enable IAM policies",

      "Effect": "Allow",

      "Principal": {

        "AWS": "arn:aws:iam::111122223333:root"

      },

      "Action": "kms:*",

      "Resource": "*"

    },

    /* STATEMENT-2 */

    {

      "Sid": "Allow access for Key Administrators",

      "Effect": "Allow",

      "Principal": {

        "AWS": [

          "arn:aws:iam::111122223333:user/KMSAdminUser",

          "arn:aws:iam::111122223333:role/KMSAdminRole"

        ]

      },

      "Action": [

        "kms:Create*",

        "kms:Describe*",

        "kms:Enable*",

        "kms:List*",

        "kms:Put*",

        "kms:Update*",

        "kms:Revoke*",

        "kms:Disable*",

        "kms:Get*",

        "kms:Delete*"

      ],

      "Resource": "*"

    },

    /* STATEMENT-3 */

    {

      "Sid": "Allow use of the key",

      "Effect": "Allow",

      "Principal": {

        "AWS": [

          "arn:aws:iam::111122223333:user/ExampleUser",

          "arn:aws:iam::111122223333:role/ExampleRole"

        ]

      },

      "Action": [

        "kms:Encrypt",

        "kms:Decrypt",

        "kms:ReEncrypt*",

        "kms:GenerateDataKey*",

        "kms:DescribeKey"

      ],

      "Resource": "*"

    }

  ]

}

 

3.2 IAM Policy

앞서 설명한 것 처럼, KMS Key 접근 제어를 할 때 IAM Policy를 함께 활용할 수 있다.

이때 아래와 같이 Key Policy에 IAM Policy를 사용하겠다는 계정 권한에 대한 명시가 되어 있어야 한다.

또, Action에는 asterisk가 아닌 IAM Policy로 제어할 수 있는 구체적인 권한들을 명시할 수도 있다.

 

{

      "Sid": "Enable IAM policies",

      "Effect": "Allow",

      "Principal": {

        "AWS": "arn:aws:iam::ACCOUNT-ID:root"

      },

      "Action": "kms:*",

      "Resource": "*"

    }

 

IAM Policy를 적용하는 방법은 다른 AWS 서비스를 사용할 때와 동일하다.

KMS 관련 권한을 가지는 Policy를 생성하고, User 혹은 Role에게 적용하면 된다.

 

 

3.3 Grant

AWS 서비스 혹은 다른 주체에게 KMS Key 사용을 일시적으로 허용하기 위한 방법이다. 이를 통해 Key Policy나 IAM Policy의 변경 없이 특정 주체에게 Key를 사용하거나 관리할 수 있는 권한을 잠시 부여할 수 있다.

 

Grant에는 크게 두가지의 개념이 있다: Grant User, Grantee.

  • Grant User
  • Grantee

Grant에는 Limit이 있기 때문에 유의해야 한다.

  • CMK당 Grant Limit: 10,000개
  • CMK당 특정 보안 주체(Principal)에 대한 Grant Limit: 500개

 

3.4 MFA

MFA를 활용하여 몇가지 주요 KMS API에 대해서 5분 안에 MFA 인증을 거쳐야만 하도록 설정할 수 있다.

이를 통해서 Key 삭제와 같이 서비스에 심각한 영향이 갈 수 있는 API에 적용해 놓으면 관리자가 실수로 해당 API를 호출하더라도 MFA까지 인증해야 처리되도록 막을 수 있게된다.

 

 {

      "Sid": "MFACriticalKMSEvents",

      "Effect": "Allow",

      "Principal": {

        "AWS": "arn:aws:iam::111122223333:user/ExampleUser"

      },

      "Action": [

          "kms:DeleteImportedKeyMaterial",

          "kms:ScheduleKeyDeletion"

     ],

      "Resource": "*",

      "Condition": {

           "NumericLessThan": {

                 "aws:MultiFactorAuthAge": "300"

           }

       }

    }

 


4. 키 관리

4.1 CMK 생성

  • 조직, 데이터 유형, 사용 환경 등에 따라 필요한 키를 적절하게 생성한다.

4.2 Multi-Account 환경

  • 키를 관리하는 관리자 계정과, 사용하는 사용자 계정을 분리해서 사용하는 형태를 주로 사용한다.
  • 암호화 대상이 있는 계정에서 키를 생성하는 것을 권장한다.

4.3 Key Rotation

  • 여러 위협에 대비해 키를 갱신하는 작업이다.
  • 자동 Key rotation 설정을 권장한다 (CMK 디폴트는 1년에 1번).
  • 키 교체 과정에서 키 ID, ARN, 리전, 정책/권한 등의 속성은 유지된다.
  • Old 키는 해당 키로 암호화된 데이터의 접근을 유지하기 위해 백업된다.
  • AWS KMS에서 생성된 Symmetric 키에 대해서만 지원된다.
  • 만약에 교체 주기를 다르게 하고 싶거나, Symmetric 키가 아니라면 수동 Key rotation 방법도 있다.

4.4 Enabling / Disabling Keys

  • Key 비활성화(Disabling)를 하면 암/복호화 관련 기능이 동작되지 않는다.
  • Key가 유출되었을 때 암호화 된 데이터를 복호화하지 못하도록 하기 위해 사용될 수 있다.
  • 비활성화는 언제든지 할 수 있고, 다시 활성화(Enabling) 할 수도 있기 떄문에, Key를 삭제하는 것 보다는 비활성화 처리 하는 것을 권장한다.
  • Key 삭제를 해야하는 상황에도 우선 비활성화 후, 문제가 없다는 것이 충분한 시간동안 검증되었을 때 삭제를 진행하는 것이 좋다.

4.5 BYOK (Bring Your Own Key) 

자체 생성한 Key를 AWS KMS에 Import해서 사용할 수 있다. 좀 더 정확히 표현하면 Key material을 Import 할 수 있다.

 

KMS의 Key는 크게 두 가지로 구성된다고 볼 수 있다: Key metadata + Key material.

Key metadata는 Key ID와 같은 해당 Key에 대한 메타 정보들에 대한 것이고, Key material은 실제 암/복호화에 사용되는 값이다. 따라서, BYOK를 통해 자체 생성한 Key를 Import한다는 것은, KMS가 Key에 대한 metadata를 생성하고, Key material 부분만 자체 생성한 Key를 적용시키는 것이다.

 

 

Key material

256비트 대칭키(Symmetric encryptioin)로 사용되는 Key만을 지원한다. (비대칭키(Asymmetric encryption)나 HMAC키는 지원하지 않는다.)

 

Expiration

Key의 만료일을 설정할 수 있다. 만료일이 되면 KMS가 해당 Key material를 삭제하고 그 즉시부터, 그 Key를 이용해 암/복호화 할 수 없다.

 

Key 교체

Import한 Key material은 교체할 수 없다. Automatic key rotation도 지원하지 않는다. Key rotation을 원하는 경우 수동으로 해줘야 한다.

 

기존에 암호화 된 데이터와 키를 KMS를 통해 관리 할 수 있을까?

KMS 에서 데이터 암호화는 크게 두 가지로 나뉜다: 1) KMS가 생성한 Data key를 이용한 암호화, 2) KMS Key를 이용한 암호화.

 

Data key를 이용한 암/복호화 방법은 Import 한 Key와 전혀 관련 없는 값으로 암/복호화를 하는 것이기 때문에, 기존에 암호화된 데이터를 이것을 이용해 복호화 할 수는 없다. KMS Key를 이용한 암/복호화는 Import 한 Key(정확히는 Key material)를 사용하는 것이지만, KMS 내부로 데이터를 전송하여 암/복호화하는 것이며 데이터 사이즈의 제한(4KB)이 있다. 만약에 데이터의 사이즈가 보장된다 하더라도 암/복호화 하려는 모든 데이터를 KMS에 요청해야 하기 때문에 성능/비용 측면에서 부담이 될 수 있다. 뿐만 아니라 Import한 Key의 경우 자동 Key 로테이션을 지원하지 않기 때문에, 필요하다면 수동으로 해야한다.

 

지원하는 암/복호화 알고리즘은 SYMMETRIC_DEFAULT(AES-GCM)이다.

 


5. 비용

예시 계산 법

  • 월별 총 비용 = (CMK 개수) * 1.00 USD + (API 요청 횟수) * 0.000003 USD
  • (CloudHSM 키 스토어를 사용하지 않고, Symmetric 키(AES)를 이용하는 경우)

서울 리전 기준

  • CMK 1개당 1.00 USD
  • 요청 10,000건당 0.03 USD
  • RSA 2048 키 관련 요청 10,000건당 0.03 USD
  • ECC GenerateDataKeyPair 요청 10,000건당 0.10 USD
  • RSA 2048 제외 비대칭 요청 10,000건당 0.15 USD
  • RSA GenerateDataKeyPair 요청 10,000건당 12.00 USD

CloudHSM 키 스토어 사용시

  • HSM별 총 시간당 1.54 USD

권장 사항

  • 비용 최소화를 위해 저희는 가용한 키를 최소한으로 유지하고, API 요청 빈도를 줄일 수 있는 방법을 검토해야 한다.
  • AWS KMS에 요청하여 응답받은 Data Key를 특정 시간동안 캐시에 보관해 활용하는 전략을 통해, API 요청 횟수와 이에 따른 비용을 줄일 수 있다 (캐시를 사용하지 않는다면 암/복호화 요청이 필요할 때마다 KMS 클라이언트를 호출해야 한다.)

 


6. 제한

6.1 Request quotas

(서울 Region을 기준으로) 초당 5500건의 요청 Limit이 있다. 그렇기 때문에 Limit을 고려하지 않을 경우, 임계치에 도달하여 API가 정상적으로 동작하지 않거나 응답 속도를 보장 받을 수 없다. 따라서, 상황에 따라 계정을 분리하여 사용하거나 구현하고자 하는 서비스의 요청량을 잘 가늠하여 진행해야 할 필요가 있다. 요청량 Limit에 걸리지 않고, 성능+비용을 개선시키고자 하는 목적으로 Data Key를 캐싱하는 것을 권장한다.

 

6.2 Resource quotas

KMS에서는 성능과 안정성 유지의 목적으로 계정+Region 별로 리소스에 대한 제한도 두고 있으며 다음과 같다. 

단, 이런 제한은 CMK에 대한 것이며, AWS Managed Key나 AWS Owned Key는 제한이 없다.

  • KMS Key 개수: 100,000개
  • KMS Key 당 별칭(Alias) 개수: 50개
  • KMS Key 당 Grant 수: 50,000회
  • Key Policy 사이즈: 32KB

 


7. 레퍼런스

반응형

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

AWS KMS 개념과 응용 - 2  (0) 2022.10.14

댓글