ablog

不器用で落着きのない技術者のメモ

S3 のデフォルト暗号化キーに使っている BYOK した CMK を入れ替える

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"
    }
}
$ 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 でデフォルト暗号化設定する
$ 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"
       }
     }
   ]
}'
$ 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"
}
$ 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.