KMS に BYOK(Bring Your Own Key) した CMK(Customer Master Key) で S3 バケットを SSE-KMS(Server-Side Encryption with AWS KMS) でデフォルト暗号化し、ファイルを S3 に Put した後、S3 のデフォルト暗号化キーを BYOK した別の CMK に変更して、S3 のオブジェクトを Get/Put して新しいキーで暗号化後に古い CMK を無効化してみた。
手順
KMS にCMKをインポートする
- KMS に CMK を空で作成する。
$ aws kms create-key --origin EXTERNAL --description imported_key { "KeyMetadata": { "Origin": "EXTERNAL", "KeyId": "d07a6b28-a314-44c0-899f-4c0b4fa18f23", "Description": "imported_key", "KeyManager": "CUSTOMER", "Enabled": false, "KeyUsage": "ENCRYPT_DECRYPT", "KeyState": "PendingImport", "CreationDate": 1540532700.471, "Arn": "arn:aws:kms:ap-northeast-1:123456789012:key/d07a6b28-a314-44c0-899f-4c0b4fa18f23", "AWSAccountId": "123456789012" } }
- 作成した CMK にエイリアス名をつける。
$ aws kms create-alias --alias-name alias/rotation-test-key --target-key-id d07a6b28-a314-44c0-899f-4c0b4fa18f23
- PublicKey と ImportToken をダウンロードする。
$ aws kms get-parameters-for-import \ --key-id d07a6b28-a314-44c0-899f-4c0b4fa18f23 \ --wrapping-algorithm RSAES_PKCS1_V1_5 \ --wrapping-key-spec RSA_2048 { "ParametersValidTo": 1540625003.173, "PublicKey": "...", "ImportToken": "..." }
- 上記のPublicKey を PublicKey1.b64、ImportToken を ImportToken1.b64 というファイル名で保存する。
- PublicKey と ImportToken をそれぞれbase64デコードして、新しいファイルで保存する。
$ openssl enc -d -a -A -in PublicKey1.b64 -out PublicKey1.bin $ openssl enc -d -a -A -in ImportToken1.b64 -out ImportToken1.bin
- KMS にインポートする CMK を作成する
$ openssl rand -out PlaintextKeyMaterial1.bin 32
- 生成した CMK を、デコードした PublicKey を使って暗号化する。
$ openssl rsautl -encrypt \ -in PlaintextKeyMaterial1.bin \ -pkcs \ -inkey PublicKey1.bin \ -keyform DER \ -pubin \ -out EncryptedKeyMaterial1.bin
- 暗号化した CMK を KMS にインポートする。
$ aws kms import-key-material --key-id d07a6b28-a314-44c0-899f-4c0b4fa18f23 \ --encrypted-key-material fileb://EncryptedKeyMaterial1.bin \ --import-token fileb://ImportToken1.bin \ --expiration-model KEY_MATERIAL_EXPIRES \ --valid-to 2018-11-01T00:00:00-00:00
S3バケットを作成し BYOK した CMK でデフォルト暗号化設定する
- S3 にバケットを作成する
$ aws s3 mb s3://kms-key-rotation-test-bucket make_bucket: kms-key-rotation-test-bucket
- 作成した S3 バケットのデフォルト暗号化キーに作成した CMK を指定する。
$ aws s3api put-bucket-encryption --bucket kms-key-rotation-test-bucket --server-side-encryption-configuration '{ "Rules": [ { "ApplyServerSideEncryptionByDefault": { "SSEAlgorithm": "aws:kms", "KMSMasterKeyID": "d07a6b28-a314-44c0-899f-4c0b4fa18f23" } } ] }'
S3 にファイルを Put する
- ファイルを S3 に Put する
$ echo 'kms key rotation test 1' > kms-key-rotation-test1.txt $ aws s3 cp kms-key-rotation-test1.txt s3://kms-key-rotation-test-bucket/ $ echo 'kms key rotation test 2' > kms-key-rotation-test2.txt $ aws s3 cp kms-key-rotation-test2.txt s3://kms-key-rotation-test-bucket/
- Put したオブジェクトの暗号化に使われている CMK を確認する
$ aws s3api head-object --bucket kms-key-rotation-test-bucket --key kms-key-rotation-test1.txt { "AcceptRanges": "bytes", "ContentType": "text/plain", "LastModified": "Fri, 26 Oct 2018 07:47:48 GMT", "ContentLength": 24, "ETag": "\"97138b7a0ea21fd4607973bd6cbd83b5\"", "ServerSideEncryption": "aws:kms", "SSEKMSKeyId": "arn:aws:kms:ap-northeast-1:123456789012:key/d07a6b28-a314-44c0-899f-4c0b4fa18f23", "Metadata": {} }
新しい CMK をインポートする
- KMS に CMK を空で作成する。
$ aws kms create-key --origin EXTERNAL --description imported_key { "KeyMetadata": { "Origin": "EXTERNAL", "KeyId": "1d3829b7-a35d-44fb-8f1d-41fc5ed229d8", "Description": "imported_key", "KeyManager": "CUSTOMER", "Enabled": false, "KeyUsage": "ENCRYPT_DECRYPT", "KeyState": "PendingImport", "CreationDate": 1540540340.387, "Arn": "arn:aws:kms:ap-northeast-1:123456789012:key/1d3829b7-a35d-44fb-8f1d-41fc5ed229d8", "AWSAccountId": "123456789012" } }
- PublicKey と ImportToken をダウンロードする。
$ aws kms get-parameters-for-import \ --key-id 1d3829b7-a35d-44fb-8f1d-41fc5ed229d8 \ --wrapping-algorithm RSAES_PKCS1_V1_5 \ --wrapping-key-spec RSA_2048 { "ParametersValidTo": 1540626803.766, "PublicKey": "...", "ImportToken": "..." }
- 上記のPublicKey を PublicKey2.b64、ImportToken を ImportToken2.b64 というファイル名で保存する。
- PublicKey と ImportToken をそれぞれbase64デコードして、新しいファイルで保存する。
$ openssl enc -d -a -A -in PublicKey2.b64 -out PublicKey2.bin $ openssl enc -d -a -A -in ImportToken2.b64 -out ImportToken2.bin
- KMSにインポートする CMK を作成する
$ openssl rand -out PlaintextKeyMaterial2.bin 32
- 生成した CMK を、デコードした PublicKey を使って暗号化する。
$ openssl rsautl -encrypt \ -in PlaintextKeyMaterial2.bin \ -pkcs \ -inkey PublicKey2.bin \ -keyform DER \ -pubin \ -out EncryptedKeyMaterial2.bin
- 暗号化した CMK を KMS にインポートする。
$ aws kms import-key-material --key-id 1d3829b7-a35d-44fb-8f1d-41fc5ed229d8 \ --encrypted-key-material fileb://EncryptedKeyMaterial2.bin \ --import-token fileb://ImportToken2.bin \ --expiration-model KEY_MATERIAL_EXPIRES \ --valid-to 2018-11-01T00:00:00-00:00
S3 のデフォルト暗号化キーを変更する
- S3 のデフォルト暗号化キーを新しく作成した CMK に変更する。
$ aws s3api put-bucket-encryption --bucket kms-key-rotation-test-bucket --server-side-encryption-configuration '{ "Rules": [ { "ApplyServerSideEncryptionByDefault": { "SSEAlgorithm": "aws:kms", "KMSMasterKeyID": "1d3829b7-a35d-44fb-8f1d-41fc5ed229d8" } } ] }'
- エイリアス"rotation-test-key"のキーIDを確認する。
$ aws kms list-aliases | jq '.Aliases[] | select(.AliasName=="alias/rotation-test-key")' { "AliasArn": "arn:aws:kms:ap-northeast-1:123456789012:alias/rotation-test-key", "AliasName": "alias/rotation-test-key", "TargetKeyId": "d07a6b28-a314-44c0-899f-4c0b4fa18f23" }
- エイリアスに紐づく CMK を変更する。
$ aws kms update-alias --alias-name alias/rotation-test-key --target-key-id 1d3829b7-a35d-44fb-8f1d-41fc5ed229d8
- エイリアス"rotation-test-key"のキーIDが変わったことを確認する
$ aws kms list-aliases | jq '.Aliases[] | select(.AliasName=="alias/rotation-test-key")' { "AliasArn": "arn:aws:kms:ap-northeast-1:123456789012:alias/rotation-test-key", "AliasName": "alias/rotation-test-key", "TargetKeyId": "1d3829b7-a35d-44fb-8f1d-41fc5ed229d8" }
新しい CMK でオブジェクトを暗号化し直す
- オブジェクト暗号化に使われているキーを確認する
$ aws s3api head-object --bucket kms-key-rotation-test-bucket --key kms-key-rotation-test1.txt { "AcceptRanges": "bytes", "ContentType": "text/plain", "LastModified": "Fri, 26 Oct 2018 07:47:48 GMT", "ContentLength": 24, "ETag": "\"97138b7a0ea21fd4607973bd6cbd83b5\"", "ServerSideEncryption": "aws:kms", "SSEKMSKeyId": "arn:aws:kms:ap-northeast-1:123456789012:key/d07a6b28-a314-44c0-899f-4c0b4fa18f23", "Metadata": {} }
- オブジェクトを Get する
$ aws s3 cp s3://kms-key-rotation-test-bucket/kms-key-rotation-test1.txt ./ download: s3://kms-key-rotation-test-bucket/kms-key-rotation-test1.txt to ./kms-key-rotation-test1.txt
- オブジェクトを Put する
$ aws s3 cp kms-key-rotation-test1.txt s3://kms-key-rotation-test-bucket/ upload: ./kms-key-rotation-test1.txt to s3://kms-key-rotation-test-bucket/kms-key-rotation-test1.txt
- Put し直したオブジェクトが新しいキーで暗号化されていることを確認する
$ aws s3api head-object --bucket kms-key-rotation-test-bucket --key kms-key-rotation-test1.txt { "AcceptRanges": "bytes", "ContentType": "text/plain", "LastModified": "Fri, 26 Oct 2018 08:43:18 GMT", "ContentLength": 24, "ETag": "\"a66d75d4b8183e6d8475ec2da993e553\"", "ServerSideEncryption": "aws:kms", "SSEKMSKeyId": "arn:aws:kms:ap-northeast-1:123456789012:key/1d3829b7-a35d-44fb-8f1d-41fc5ed229d8", "Metadata": {} }
古いキーを無効化する
- 古いキーを無効化する
$ aws kms disable-key --key-id d07a6b28-a314-44c0-899f-4c0b4fa18f23
- 新しいキーで暗号化し直したオブジェクトはダウンロードできる。
$ aws s3 cp s3://kms-key-rotation-test-bucket/kms-key-rotation-test1.txt ./ download: s3://kms-key-rotation-test-bucket/kms-key-rotation-test1.txt to ./kms-key-rotation-test1.txt
- 古い CMK で Put したオブジェクトはダウンロードできない。
$ aws s3 cp s3://kms-key-rotation-test-bucket/kms-key-rotation-test2.txt ./ download failed: s3://kms-key-rotation-test-bucket/kms-key-rotation-test2.txt to ./kms-key-rotation-test2.txt An error occurred (KMS.DisabledException) when calling the GetObject operation: arn:aws:kms:ap-northeast-1:123456789012:key/d07a6b28-a314-44c0-899f-4c0b4fa18f23 is disabled.