Amazon Web Services ブログ

Amazon S3 暗号化を S3 マネージドから AWS KMS に変更する



Amazon Simple Storage Service (Amazon S3) を使用するお客様は、サーバー側のオブジェクト暗号化 (SSE) に S3 マネージド暗号化キー (SSE-S3) を利用することがよくあります。多くのお客様の場合、SSE-S3 を使用することにより、データを保護するためのセキュリティ要件を満たしています。一方で、一部のお客様の場合、最初は SSE-S3 が要件を満たしていたはずが、時間の経過とともに要件が変更された可能性があります。たとえば、顧客が別の標準セットに対する準拠を必要とする新しいビジネスを拡張している場合があります。別の例として、分析を使用するお客様の多くは、機密データ以外を使用して概念実証を実行することから始めます。分析プラットフォームから価値を引き出すにつれて、さまざまなデータソースからさらに多くのデータを追加し、このデータ集約によって分類が変更されることがよくあります。暗号化キーにアクセスできるユーザーをより詳細に制御できるようにすることで、暗号化キーを処理するための追加制御を実装しなければならない場合があります。また、ログ記録と監査を分離したり、ストレージと暗号化を別々に認証するための PCI-DSS コンプライアンス要件をサポートしたりすることもできます。AWS マネージドキーとカスタマーマネージドキーの違いについては、このブログ記事をご覧ください。

より強力なセキュリティとコンプライアンスの要件を満たすために、一部のお客様は、暗号化モデルを SSE-S3 から SSE-KMS に変更したいと思う場合があります。SSE-KMS は、暗号化に AWS Key Management Service (AWS KMS) を使用します。そうすることで、許容が大きすぎるポリシーからの保護など、いくつかの追加利点を提供できます。たとえば、個々のユーザーやロールではなく、過度に広いデータへのアクセスを許可するバケットポリシーを追加します。KMS キーを使用して暗号化を実装することにより、リソースにアクセスする者は、Amazon S3 ポリシーアクセスと、データを復号化するための KMS キーへのアクセスを必要とします。カスタマーマネージドキーで AWS KMS を使用することを選択したお客様には、追加のコンプライアンス要件をサポートできる次の利点もご利用いただけます。

  • キーの所有権を維持してアクセスを取り消し、データへのアクセスを不可能にします。
  • 独自のコンプライアンス要件に合わせて、AWS KMS コンソールから監査可能なカスタマーマネージド CMK を作成、ローテーション、無効化することができます。
  • AWS KMS のセキュリティ管理は、暗号化関連のコンプライアンス要件を満たすのに役立ちます。

この記事では、4 つのことを説明します。

  • 暗号化に KMS キーを使用するよう、バケットにデフォルトの暗号化を設定する方法。
  • 暗号化に KMS キーを使用するよう、既存のオブジェクトを変更する方法。
  • AWS KMS を使用した追加保護が、許容が大きすぎるポリシーに対して提供されます。
  • 特定の KMS キーが暗号化のリクエストを受けた場合にのみアップロードを許可するバケットポリシーを設定する方法。

この記事で説明した方法で前述のリストの利点または要件を提供することができます。ただし、暗号化をより詳細に制御することに伴うトレードオフのいくつかについて注意深く理解する必要があります。AWS KMS は、毎秒のリクエスト数 (RPS) 割り当てを確保して、高速で復元力のあるサービスを提供できるようにします。たとえば、AWS KMS へのデフォルトのリクエスト数は、5,500〜30,000 RPS 範囲に制限されています (AWS リージョンによって異なります)。AWS KMS の制限と制限の引き上げをリクエストする方法については、AWS KMS の制限をご覧ください。AWS KMS リクエストの割り当ては、カスタムキーストアの割り当てを除いて調整可能です。クォータを超える必要がある場合は、Service Quotas でクォータの引き上げをリクエストできます。Service Quotas コンソールまたは RequestServiceQuotaIncrease 操作を使用します。詳細については、Service Quotas ユーザーガイドクォータの引き上げリクエストをご覧ください。AWS KMS の Service Quotas が AWS リージョンで利用できない場合は、AWS サポートセンターにアクセスしてケースを作成してください。

カスタマーマネージドキーで AWS KMS を使用する場合も、コストに関して考慮するべき事項があります。この影響を理解しやすくするために、欧州 (ロンドン) リージョンの S3 標準に保存されている 10 TB のうち、1 GB のオブジェクトを保存するとします。1 か月間、オブジェクトを 2,000,000 回ダウンロードし、そのうちの 10,000 個をすべて同じリージョン内で更新されたバージョンに上書きします。

  • S3 コスト = 240.86 USD/月

SSE-S3 を使用した場合、こちらが総コストになります。ただし、暗号化を SSE-KMS に変更した場合は、1 か月で 10,000 件の暗号化リクエストと 2,000,000 件の復号化リクエストを考慮する必要があります。

  • AWS KMS CMK 1 つ = 1 USD
  • 暗号化と復号化 = 6 USD

AWS SSE-KMS への移行サイズを決定するには、S3 インベントリレポートまたは新しい Amazon Macie のいずれかを使用して、オブジェクトの数とバイト数を識別します。これを使用して、移行のコストモデルを作成できます。クォータがどのように影響するかを理解するには、AWS KMS 開発者ガイドのドキュメントを参照してください。

この記事では、AWS コマンドラインインターフェイス (AWS CLI)AWS マネジメントコンソールを組み合わせて AWS サービスとやり取りしています。AWS CLI をまだインストールしていない場合は、このガイド通りにインストールしてください。

この記事の後半ではコマンドを表示しており、環境に合わせてパラメータを変更する必要があります。これには、バケット名「kms-encryption-demo」および ARN または「<create-access-key コマンドからのアクセスキー>」などの特定リファレンスの置き換えが含まれます。 このブログ記事のコードは、暗号化キーの変更をスクリプト化する方法の例として提供されているのでご注意ください。本番環境で使用する前に、これらの変更を慎重にテストして理解してください。

この最初のステップでは、新しいバケットを作成してオブジェクトをアップロードし、さまざまな暗号化シナリオでの S3 コンテンツへのアクセスの違いを示します。

デフォルトのバケット暗号化設定

最初に、SSE-S3 暗号化を有効にしてバケットを作成し、ファイルをアップロードします。
AWS CLI で次のコマンドを実行します (必要に応じて編集してください)。

aws s3 mb s3://kms-encryption-demo
aws s3api put-bucket-encryption --bucket kms-encryption-demo --server-side-encryption-configuration '
{
	"Rules": [{
		"ApplyServerSideEncryptionByDefault": {
			"SSEAlgorithm": "AES256"
		}
	}]
}'
echo 'Lots of data' > test-1.log
echo 'Even more data' > test-2.log
echo 'The most data' > test-3.log
aws s3 cp test-1.log s3://kms-encryption-demo/

最後に、アップロードしたオブジェクトをクエリして、サーバー側の暗号化が正しく設定されていることを確認します。次のコマンドでこれを行います。

aws s3api head-object --bucket kms-encryption-demo --key test-1.log

AWS CLI から受け取ったレスポンスを見ると、オブジェクトに S3 サーバー側の暗号化が設定されていることがわかります。これは、「AES256」に設定されている ServerSideEncryption フィールドを見るとわかります。

AWS KMS キーを作成する

AWS KMS は、使いやすいキー管理サービスです。AWS KMS を使用すれば、さまざまな AWS サービスで使用するキーを簡単に作成、管理、制御して、データを暗号化および復号化できます。

この次のステップでは、新しいキーを作成します。次に、KMS キーを使用するようにバケットのデフォルト暗号化を設定し、新しいファイルをアップロードして、新しいキーで暗号化されていることを確認します。これを実現するには、まずこの記事通りに KMS キーを作成します。

AWS KMS を構成するときは、次の値を使用します。

  • エイリアス: kms-demo
  • 説明: AWS KMS デモ
  • 詳細オプション: デフォルトを維持
  • タグ: 空白のままにする
  • 主な管理者権限: ユーザー名またはグループ
  • キー使用権限ユーザー名またはグループ

新しいキーを使用するようにバケットにデフォルトの暗号化を設定する

キーが作成されたら、以前作成したバケットにそのキーを使用するよう S3 に指示する必要があります。これを行うには、AWS CLI で次のコマンドを実行します。

aws s3api put-bucket-encryption --bucket kms-encryption-demo --server-side-encryption-configuration '{
        "Rules": [
            {
                "ApplyServerSideEncryptionByDefault": {
                    "SSEAlgorithm": "aws:kms",
                    "KMSMasterKeyID": "arn:aws:kms:eu-west-2:1111111111111:key/90258e51-2441-3332-ff43-62a87177c8ac"
                }
            }
        ]
    }'

新しいファイルをアップロードし、オブジェクトに適用された暗号化を確認する

次のコマンドを実行して、新しいファイルをバケットにアップロードし、使用中の暗号化を確認します。

aws s3 cp test-2.log s3://kms-encryption-demo/
aws s3api head-object --bucket kms-encryption-demo --key test-1.log
aws s3api head-object --bucket kms-encryption-demo --key test-2.log

AWS CLI から受け取ったレスポンスを見ると、最初のオブジェクトが同じ SSE 暗号化セットを持っていることがわかります。さらに、2 番目のオブジェクトの値「SSEKMSKeyId」が前に作成した KMS キーに設定されていることがわかります。

新しいユーザーで既存のファイルアクセスをテストする

AWS KMS が提供する詳細なアクセス許可を示すために、S3 バケットとオブジェクトへの完全なアクセス権を持つ新しいユーザーを作成し、両方のファイルにアクセスしてみます。

これを行うには、AWS CLI で次のコマンドを実行します。

aws iam create-user --user-name kms-demo
echo '{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::kms-encryption-demo",
                "arn:aws:s3:::kms-encryption-demo/*"
            ]
        }
    ]
}' > policy.json
aws iam create-policy --policy-name kms-demo --policy-document file://policy.json
aws iam attach-user-policy --user-name kms-demo --policy-arn <ARN returned from the create policy command, e.g. <arn:aws:iam::11111111111:policy/kms-demo >
aws iam create-access-key --user-name kms-demo
export AWS_ACCESS_KEY_ID=<access key from the create-access-key command>
export AWS_SECRET_ACCESS_KEY=<secret key from the create-access-key command>
aws s3api get-object --bucket kms-encryption-demo --key test-1.log .
aws s3api get-object --bucket kms-encryption-demo --key test-2.log .
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_KEY

これらのコマンドを完了すると、デフォルトの S3 暗号化が使用されているため、ユーザー kms-demo が test-1.log に正常にアクセスできることがわかります。ただし、同じユーザーが 2 番目のファイル (test-2.log) にアクセスしようとすると、オブジェクトを復号化するための KMS キーにアクセスできないため、「AccessDenied」が表示されます。

暗号化に AWS KMS キーを使用するようにバケット内のすべてのオブジェクトを更新する

バケット内のすべてのオブジェクトを変更するために、AWS CLI を使用できます。aml やタグなどの他のメタデータをコピーします。これらを明示的に指定しなければならない場合があります。詳細については、こちらの AWS CLI の使用方法に関するブログ記事をご覧ください。これを行う方法の例は次のとおりです。

aws s3 cp s3://kms-encryption-demo/ s3://kms-encryption-demo/ --recursive --sse-kms-key-id arn:aws:kms:eu-west-2:1111111111111:key/90258e51-2441-3332-ff43-62a87177c8ac --sse aws:kms

S3 バケットに数百万個の項目がある場合、完了するまでに時間がかかる可能性があります。S3 バッチ操作を使用して、タスクの面倒を見るジョブをオフロードできます。これを達成するための詳細は、このブログ記事をご覧ください。

このブログ記事の冒頭にあるコストの例で説明したように、この操作の実行に関連する追加コストが発生します。この追加コストは、数十億個のオブジェクトにわたって重大なコストになる可能性があります。これらは、AWS KMS 暗号化、および取得時に AWS KMS 復号化を行う場合、オブジェクトを取得および配置するための料金です。オブジェクトを SSE-S3 から SSE-KMS に変換する前に、コストモデル化を行って、特定のユースケースで発生する費用について理解されることをお勧めします。

AWS KMS キー暗号化の強制

この最後のセクションでは、ユーザーが最初の手順で設定したデフォルトの AWS KMS 暗号化を上書きできないようにするバケットポリシーを設定します。これを行うには、AWS CLI で次のコマンドを実行します。

echo '{
    "Version": "2012-10-17",
    "Id": "PutObjPolicy",
    "Statement": [
	      {
            "Sid": "RequireKMSEncryption",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::kms-encryption-demo/*",
            "Condition": {
                "StringNotLikeIfExists": {
                    "s3:x-amz-server-side-encryption-aws-kms-key-id": "arn:aws:kms:eu-west-2:11111111111:key/d0344c2d-1b23-47ff-917a-3bea854ad3f9"
                }
            }
        }
    ]
}' > bucket_policy.json
aws s3api put-bucket-policy --bucket kms-encryption-demo --policy file://bucket_policy.json
aws s3 cp test-3.log s3://kms-encryption-demo/ --sse

正しい暗号化なしでファイルをアップロードしようとすると、暗号化タイプが正しくないため、アップロードが拒否されます。

前のアクションでは、「test-3.log」をアップロードして、SSE-S3 暗号化を指定しようとしました。生成された KMS キーによる暗号化のみを許可するポリシーをバケットに添付したため、この試みは失敗しました。

同じ操作を試みましたが、暗号化タイプを指定しない場合はドキュメントをアップロードできます。

aws s3 cp test-3.log s3://kms-encryption-demo/
aws s3api head-object --bucket kms-encryption-demo --key test-3.log

オブジェクトの最終チェックを実行すると、今回は正しい暗号化が設定されていることがわかります。

クリーンアップ

請求が継続的に発生しないようにするには、このチュートリアル中に作成したリソースをクリーンアップする必要があります。これを行うには、AWS CLI で次のコマンドを実行します。

aws kms schedule-key-deletion --key-id d0344c2d-1b23-47ff-917a-3bea854ad3f9 --pending-window-in-days 7
aws iam detach-user-policy --user-name kms-demo --policy-arn arn:aws:iam::11111111111:policy/kms-demo
aws iam delete-user --user-name kms-demo
aws iam delete-policy --policy-arn arn:aws:iam::11111111111:policy/kms-demo
aws s3 rb s3://kms-encryption-demo --force

まとめ

この記事では、次のことを示しました。

  1. バケットにデフォルトの暗号化を設定して、新しいオブジェクトのアップロードを自動的に暗号化する方法。
  2. SSE-KMS が許容が大きすぎるアクセスポリシーに提供する追加保護。
  3. AWS CLI を使用して少数のオブジェクト暗号化を更新し、バッチオペレーションでこれを達成するためにリソースをポイントする方法。
  4. 特定タイプの暗号化が指定されている場合にのみオブジェクトをアップロードできるようにする方法。

このブログ記事で説明されている方法は、S3 暗号化を SSE-KMS に変更する方法を示しており、コンプライアンス要件を満たすのに役立ちます。データセキュリティに関するより厳格なポリシーに準拠する必要があるため、コンプライアンスのニーズが時間の経過とともに変化することに気づいたお客様にとって役立ちます。これは、ユーザーが S3 だけでなく AWS KMS キーに対するアクセス許可も必要とするのが原因です。Well Architected セキュリティの柱で説明されているように、詳細防御アプローチと整合しています。

これらのメソッドは、セキュリティ体制の改善に役立つ多くの追加コントロールの一部を構成します。AWS ConfigAWS Organizations (SCP ポリシー) などのサービスでこれらのメソッドを使用すれば、S3 バケットに必要なポリシーを監視および適用するのに役立つ追加コントロールを実装できます。記事をお読みいただきありがとうございます。ご質問やご意見がおありの場合はコメント欄にお寄せください。