AWS KMSとは

AWS Key Management Service とは

AWS Key Management Service (AWS KMS) は、データの暗号化に使用される暗号化キーの作成と管理を容易にするマネージド型サービスです。AWS KMS は、Amazon Elastic Block Store (Amazon EBS)、Amazon Simple Storage Service (Amazon S3)、Amazon Redshift、Amazon Elastic Transcoder、Amazon WorkMail、Amazon Relational Database Service (Amazon RDS) などの他の AWS サービスと統合されており、ユーザーが管理する暗号化キーでのデータの暗号化を簡単にします。また AWS KMS は AWS CloudTrail とも統合されており、キーの使用ログを表示できるため、監査、規制、およびコンプライアンスの要求に応えるために役立ちます。

CloudformationでCMKを作成

CSK作成

AWS Key Management Service (AWS KMS) でカスタマーマスターキー (CMK) を作成します。

AWS::KMS::Key

定義ファイル

  • key.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
AWSTemplateFormatVersion: "2010-09-09"
Description: "Cloudformation Sample : Create Sample KMS Key"
Parameters:
  pTagKey:
    Type: String
  pTagValue:
    Type: String
Resources:
  SampleKey:
    Type: "AWS::KMS::Key"
    Properties:
      Description: "A sample key"
      KeyPolicy:
        Version: "2012-10-17"
        Id: "key-default-1"
        Statement:
          -
            Sid: Enable IAM User Permissions
            Effect: Allow
            Principal:
              AWS: !Join
                - ''
                - - 'arn:aws:iam::'
                  - !Ref 'AWS::AccountId'
                  - ':root'
            Action: 'kms:*'
            Resource: '*'
      Tags:
        - Key: !Ref pTagKey
          Value: !Ref pTagValue
Outputs:
  SampleKey:
    Value: !Ref SampleKey
    Export:
      Name: SampleKey

Cloudformationの実行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$ CF_TAG_KEY=service
$ CF_TAG_NAME=sample
$ CF_STACK_NAME=sampleKMSKey

$ aws cloudformation create-stack \
--tags Key=${CF_TAG_KEY},Value=${CF_TAG_NAME} \
--stack-name ${CF_STACK_NAME} \
--template-body file:///$PWD/key.yaml \
--parameters \
ParameterKey=pTagKey,ParameterValue=${CF_TAG_KEY} \
ParameterKey=pTagValue,ParameterValue=${CF_TAG_NAME} \
| jq .

CSKのAliasを作成

AWS Key Management Service (AWS KMS) でカスタマーマスターキー (CMK) の表示名を作成します。

定義ファイル

  • alias.yaml
1
2
3
4
5
6
7
8
AWSTemplateFormatVersion: "2010-09-09"
Description: "Cloudformation Sample : Create Sample KMS Key Alias"
Resources:
  SampleKeyAlias:
    Type: AWS::KMS::Alias
    Properties:
      AliasName: alias/SampleKeyAlias
      TargetKeyId: !ImportValue SampleKeyARN

Cloudformationの実行

1
2
3
4
5
6
7
8
9
$ CF_TAG_KEY=service
$ CF_TAG_NAME=sample
$ CF_STACK_NAME=sampleKMSKeyAlias

$ aws cloudformation create-stack \
--tags Key=${CF_TAG_KEY},Value=${CF_TAG_NAME} \
--stack-name ${CF_STACK_NAME} \
--template-body file:///$PWD/alias.yaml \
| jq .

作成されたCSKの確認

AWS CLIで確認

AWS CLI KMS

1
$ aws kms list-keys
1
2
3
4
5
6
7
8
{
    "Keys": [
        {
            "KeyId": "XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXXXXXXX",
            "KeyArn": "arn:aws:kms:ap-northeast-1:123456789012:key/XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXXXXXXX"
        }
    ]
}

alias(SampleKeyAlias)で検索

1
$ aws kms list-aliases | jq '.Aliases[] | select( .AliasName | test("SampleKeyAlias"))'
1
2
3
4
5
{
  "AliasName": "alias/SampleKeyAlias",
  "AliasArn": "arn:aws:kms:ap-northeast-1:123456789012:alias/SampleKeyAlias",
  "TargetKeyId": "XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXXXXXXX"
}

暗号化(encrypt)

AWS CLI KMS encrypt

ここでは、aliasを使って暗号化します。

1
2
3
$ aws kms encrypt \
--key-id alias/SampleKeyAlias \
--plaintext "I am seacret word"

出力

1
2
3
4
{
    "CiphertextBlob": "AQICAHgiNRl+XlUIXRhw4+tLNMNgYcJYxkGHTirG5cXZvdUbxwHwVFktPdlZsI7tifaHUVk2AAAAbzBtBgkqhkiG9w0BBwagYDBeAgEAMFkGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMwmujQIyOGHFjqkyJAgEQgCyWHiZUyquUAVWYOOwE0d2X+Ij99UJatuYxTUSaWvrjQcnTnjhUHuMKTPXAbw==",
    "KeyId": "arn:aws:kms:ap-northeast-1:123456789012:key/XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXXXXXXX"
}

CiphertextBlobが、“I am seacret word"を暗号化してbase64でエンコードしたもののようです。

マニュアルの使い方の例としては、CiphertextBlobをbase64でデコードしたものバイナリをファイルに保存するようです。

1
2
3
4
5
6
$ aws kms encrypt \
--key-id alias/SampleKeyAlias \
--plaintext "I am seacret word" \
--output text \
--query CiphertextBlob \
| base64 --decode > ExampleEncryptedFile

複合化(decrypt)

次にExampleEncryptedFileの中身を復号化して取り出してみましょう。

AWS CLI KMS decrypt

まずは、複合だけしてみる。

1
2
$ aws kms decrypt \
--ciphertext-blob fileb://ExampleEncryptedFile
1
2
3
4
{
    "KeyId": "arn:aws:kms:ap-northeast-1:123456789012:key/XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXXXXXXX",
    "Plaintext": "SSBhbSBzZWFjcmV0IHdvcmQ="
}

ファイルの中にKeyIdが含まれているので指定しなくても問題ないようですね。

取り出します。

1
2
3
4
5
$ aws kms decrypt \
--ciphertext-blob fileb://ExampleEncryptedFile \
--output text \
--query Plaintext \
| base64 --decode > ExamplePlaintextFile
1
2
$ cat ExamplePlaintextFile
I am seacret word

問題なくとりだせました。

まとめ

ソースコードにAPIのKEY等を埋め込めないことがほとんどなので、KMSつかってセキュアに扱いましょう。

使い方も慣れれば簡単ですね。次は、Lambdaでの使い方を整理していきます。