S3 バケットのデフォルト暗号化に使う CMK(Customer Master Key) を KMS(Key Management Service) で生成したものから BYOK(Bring Your Own Key) に変えてみた。
手順
KMS に CMK を作成する
- CMK を作成する
$ aws kms create-key { "KeyMetadata": { "Origin": "AWS_KMS", "KeyId": "c3c1fb86-168d-40ca-9489-90cf2bd49dfa", ★ "Description": "", "KeyManager": "CUSTOMER", "Enabled": true, "KeyUsage": "ENCRYPT_DECRYPT", "KeyState": "Enabled", "CreationDate": 1540799362.916, "Arn": "arn:aws:kms:ap-northeast-1:123456789012:key/c3c1fb86-168d-40ca-9489-90cf2bd49dfa", "AWSAccountId": "123456789012" } }
- エイリアス名をつける
$ aws kms create-alias --alias-name alias/kms-gen-key --target-key-id c3c1fb86-168d-40ca-9489-90cf2bd49dfa
S3バケットのデフォルト暗号化を設定してファイルを Put する
- S3バケットを作成する
$ aws s3 mb s3://kms-key-change-test make_bucket: kms-key-change-test
- デフォルト暗号化設定を行う
$ aws s3api put-bucket-encryption --bucket kms-key-change-test --server-side-encryption-configuration '{ "Rules": [ { "ApplyServerSideEncryptionByDefault": { "SSEAlgorithm": "aws:kms", "KMSMasterKeyID": "c3c1fb86-168d-40ca-9489-90cf2bd49dfa" ★ } } ] }'
- デフォルト暗号化設定を確認する
$ aws s3api get-bucket-encryption --bucket kms-key-change-test { "ServerSideEncryptionConfiguration": { "Rules": [ { "ApplyServerSideEncryptionByDefault": { "KMSMasterKeyID": "c3c1fb86-168d-40ca-9489-90cf2bd49dfa", ★ "SSEAlgorithm": "aws:kms" } } ] } }
- ファイルを Put する
$ echo 'Test' > test1.txt $ cp test1.txt test2.txt $ cp test1.txt test3.txt $ aws s3 cp test1.txt s3://kms-key-change-test/ upload: ./test1.txt to s3://kms-key-change-test/test1.txt $ aws s3 cp test2.txt s3://kms-key-change-test/ upload: ./test2.txt to s3://kms-key-change-test/test2.txt $ aws s3 cp test3.txt s3://kms-key-change-test/ upload: ./test3.txt to s3://kms-key-change-test/test3.txt
- オブジェクト暗号化に使われているキーを確認する
$ aws s3api head-object --bucket kms-key-change-test --key test1.txt { "AcceptRanges": "bytes", "ContentType": "text/plain", "LastModified": "Mon, 29 Oct 2018 08:01:00 GMT", "ContentLength": 5, "ETag": "\"028422466ea4c14965264d1666728a7c\"", "ServerSideEncryption": "aws:kms", "SSEKMSKeyId": "arn:aws:kms:ap-northeast-1:123456789012:key/c3c1fb86-168d-40ca-9489-90cf2bd49dfa", ★ "Metadata": {} }
KMS に BYOK する
- CMK を作成する
$ aws kms create-key --origin EXTERNAL --description byok_key { "KeyMetadata": { "Origin": "EXTERNAL", "KeyId": "2afa832b-d531-40fe-ac8c-4e34a578939a", ★ "Description": "byok_key", "KeyManager": "CUSTOMER", "Enabled": false, "KeyUsage": "ENCRYPT_DECRYPT", "KeyState": "PendingImport", "CreationDate": 1540801553.271, "Arn": "arn:aws:kms:ap-northeast-1:123456789012:key/2afa832b-d531-40fe-ac8c-4e34a578939a", "AWSAccountId": "123456789012" } }
- エイリアス名をつける
$ aws kms create-alias --alias-name alias/kms-byok-key --target-key-id 2afa832b-d531-40fe-ac8c-4e34a578939a
- PublicKey と ImportToken をダウンロードする。
$ aws kms get-parameters-for-import \ --key-id 2afa832b-d531-40fe-ac8c-4e34a578939a \ --wrapping-algorithm RSAES_PKCS1_V1_5 \ --wrapping-key-spec RSA_2048
- 上記のPublicKey を PublicKey.b64、ImportToken を ImportToken.b64 というファイル名で保存する。
- PublicKey と ImportToken をそれぞれbase64デコードして、新しいファイルで保存する。
$ openssl enc -d -a -A -in PublicKey.b64 -out PublicKey.bin $ openssl enc -d -a -A -in ImportToken.b64 -out ImportToken.bin
- KMS にインポートする CMK を作成する
$ openssl rand -out PlaintextKeyMaterial.bin 32
- 生成した CMK を、デコードした PublicKey を使って暗号化する。
$ openssl rsautl -encrypt \ -in PlaintextKeyMaterial.bin \ -pkcs \ -inkey PublicKey.bin \ -keyform DER \ -pubin \ -out EncryptedKeyMaterial.bin
- CMK を KMS にインポートする。
$ aws kms import-key-material --key-id 2afa832b-d531-40fe-ac8c-4e34a578939a \ --encrypted-key-material fileb://EncryptedKeyMaterial.bin \ --import-token fileb://ImportToken.bin \ --expiration-model KEY_MATERIAL_EXPIRES \ --valid-to 2018-11-01T00:00:00-00:00
S3バケットのデフォルト暗号化キーを BYOK した CMK に変更する
- デフォルト暗号化キーを BYOK した CMK に変更する
$ aws s3api put-bucket-encryption --bucket kms-key-change-test --server-side-encryption-configuration '{ "Rules": [ { "ApplyServerSideEncryptionByDefault": { "SSEAlgorithm": "aws:kms", "KMSMasterKeyID": "2afa832b-d531-40fe-ac8c-4e34a578939a" ★ } } ] }'
- デフォルト暗号化キーが変更されていることを確認する
$ aws s3api get-bucket-encryption --bucket kms-key-change-test { "ServerSideEncryptionConfiguration": { "Rules": [ { "ApplyServerSideEncryptionByDefault": { "KMSMasterKeyID": "2afa832b-d531-40fe-ac8c-4e34a578939a", ★ "SSEAlgorithm": "aws:kms" } } ] } }
S3のオブジェクトを Get/Put して BYOK した CMK で暗号化し直す
- Get/Put して BYOK したキーで暗号化し直す
$ aws s3 cp s3://kms-key-change-test/test.txt ./ $ aws s3 cp test.txt s3://kms-key-change-test/ $ aws s3 cp s3://kms-key-change-test/test2.txt ./ $ aws s3 cp test2.txt s3://kms-key-change-test/
- オブジェクト暗号化に使われているキーを確認する
$ aws s3api head-object --bucket kms-key-change-test --key test1.txt { "AcceptRanges": "bytes", "ContentType": "text/plain", "LastModified": "Mon, 29 Oct 2018 08:37:32 GMT", "ContentLength": 5, "ETag": "\"f5b4a98e6bbdce444ebe6eaabbf5854b\"", "ServerSideEncryption": "aws:kms", "SSEKMSKeyId": "arn:aws:kms:ap-northeast-1:123456789012:key/2afa832b-d531-40fe-ac8c-4e34a578939a", "Metadata": {} } $ aws s3api head-object --bucket kms-key-change-test --key test1.txt { "AcceptRanges": "bytes", "ContentType": "text/plain", "LastModified": "Mon, 29 Oct 2018 08:37:32 GMT", "ContentLength": 5, "ETag": "\"f5b4a98e6bbdce444ebe6eaabbf5854b\"", "ServerSideEncryption": "aws:kms", "SSEKMSKeyId": "arn:aws:kms:ap-northeast-1:123456789012:key/2afa832b-d531-40fe-ac8c-4e34a578939a", "Metadata": {} }
古い CMK を無効化する
- 古いキーを無効化する
$ aws kms disable-key --key-id c3c1fb86-168d-40ca-9489-90cf2bd49dfa
- 無効化されていることを確認する。
$ aws kms describe-key --key-id c3c1fb86-168d-40ca-9489-90cf2bd49dfa { "KeyMetadata": { "Origin": "AWS_KMS", "KeyId": "c3c1fb86-168d-40ca-9489-90cf2bd49dfa", "Description": "", "KeyManager": "CUSTOMER", "Enabled": false, ★ "KeyUsage": "ENCRYPT_DECRYPT", "KeyState": "Disabled", "CreationDate": 1540799362.916, "Arn": "arn:aws:kms:ap-northeast-1:123456789012:key/c3c1fb86-168d-40ca-9489-90cf2bd49dfa", "AWSAccountId": "123456789012" } }
- 新しいキーで暗号化し直したオブジェクトはダウンロードできる。
$ aws s3 cp s3://kms-key-change-test/test1.txt ./ download: s3://kms-key-change-test/test1.txt to ./test1.txt
- 古い CMK で Put したオブジェクトはダウンロードできない。
$ aws s3 cp s3://kms-key-change-test/test3.txt ./ download failed: s3://kms-key-change-test/test3.txt to ./test3.txt An error occurred (KMS.DisabledException) when calling the GetObject operation: arn:aws:kms:ap-northeast-1: 123456789012:key/c3c1fb86-168d-40ca-9489-90cf2bd49dfa is disabled.
- オブジェクトが暗号化されている CMK を確認する。
$ aws s3 ls --recursive s3://kms-key-change-test|perl -lane 'print $F[3]'|xargs -n1 aws s3api head-object --bucket kms-key-change-test --key|jq '.|@text "\(.SSEKMSKeyId)"' "arn:aws:kms:ap-northeast-1:123456789012:key/2afa832b-d531-40fe-ac8c-4e34a578939a" "arn:aws:kms:ap-northeast-1:123456789012:key/2afa832b-d531-40fe-ac8c-4e34a578939a" "arn:aws:kms:ap-northeast-1:123456789012:key/c3c1fb86-168d-40ca-9489-90cf2bd49dfa"