security
A
信頼度ランク
| S | 公式ソース確認済み |
| A | 成功実績多数・失敗例少数 |
| B | 賛否両論 |
| C | 動作未確認・セキュリティリスク高 |
| Z | 個人所感 |
S3暗号化の全種類比較 — SSE-S3/SSE-KMS/SSE-C/クライアントサイド
S3の4種類の暗号化方式(SSE-S3, SSE-KMS, DSSE-KMS, SSE-C, クライアントサイド)を比較。鍵管理の違い、KMS API呼び出しコスト、バケットキー設定、試験頻出ポイントを解説。
一言結論
S3暗号化は「誰が鍵を管理するか」と「監査ログが必要かどうか」で方式を選び、SSE-KMSを使う場合はS3 Bucket Keyを必ず有効化してKMS APIコストを最大99%削減することが大規模利用の前提条件だ。
S3の暗号化オプション一覧
S3の暗号化は「誰が鍵を管理するか」によって4種類に分類される。
| 方式 | 鍵管理者 | KMSコスト | 監査ログ | 特記事項 |
|---|---|---|---|---|
| SSE-S3 (AES-256) | AWS | なし | なし | デフォルト。最も簡単 |
| SSE-KMS | AWS/ユーザー | あり | CloudTrailに記録 | 鍵管理・監査が必要な場合 |
| DSSE-KMS | AWS/ユーザー | あり | CloudTrailに記録 | 二重暗号化(規制対応) |
| SSE-C | ユーザー | なし | CloudTrailに記録 | 鍵をユーザーが管理 |
| クライアントサイド | ユーザー | なし | なし | 暗号化後にS3に保存 |
SSE-KMS の詳細
SSE-KMSはS3オブジェクトをKMSキーで暗号化する。アップロード時にKMSのGenerateDataKey、ダウンロード時にDecryptのAPI呼び出しが発生する。
# SSE-KMSでオブジェクトをアップロード
aws s3 cp myfile.txt s3://my-bucket/ \
--sse aws:kms \
--sse-kms-key-id arn:aws:kms:ap-northeast-1:123456789012:key/xxx
# バケットのデフォルト暗号化をSSE-KMSに設定
aws s3api put-bucket-encryption \
--bucket my-bucket \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:ap-northeast-1:123456789012:key/xxx"
},
"BucketKeyEnabled": true
}]
}'
S3 Bucket Key — KMSコスト削減
S3 Bucket Keyを有効にすると、オブジェクトごとにKMS APIを呼び出さず、バケットレベルのデータキーを使って暗号化する。大量のオブジェクトがある場合にKMSコストを最大99%削減できる。
通常のSSE-KMS:
各オブジェクトアップロード → KMS GenerateDataKey呼び出し
各オブジェクトダウンロード → KMS Decrypt呼び出し
S3 Bucket Key有効:
バケットキー(データキー)をS3が一定期間キャッシュ
→ KMS API呼び出し頻度が大幅減少
デメリット:CloudTrailのKMSイベントが減るため、オブジェクトレベルの詳細な監査には適さない。
SSE-C の特徴と要件
SSE-Cはユーザーが鍵を管理し、リクエスト時に鍵を渡す方式だ。
# SSE-Cでのアップロード(HTTPS必須)
aws s3 cp myfile.txt s3://my-bucket/ \
--sse-c AES256 \
--sse-c-key "$(openssl rand -base64 32)"
# SSE-Cでのダウンロード(同じ鍵が必要)
aws s3 cp s3://my-bucket/myfile.txt ./myfile.txt \
--sse-c AES256 \
--sse-c-key "保存しておいた鍵"
重要な制約:
- HTTPSが必須(HTTPでは鍵が平文で送信されるため自動拒否)
- AWSは鍵を保存しない → 鍵を失うとオブジェクト復号不可能
- AWS CLIでSSE-Cを使う場合、SDKから直接使う必要がある(マネジメントコンソール非対応)
クライアントサイド暗号化
S3にアップロードする前にクライアント側で暗号化する。S3には暗号化済みのバイナリが保存される。
import boto3
from aws_encryption_sdk import EncryptionSDKClient, CommitmentPolicy
enc_client = EncryptionSDKClient(
commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
)
# 暗号化
ciphertext, _ = enc_client.encrypt(
source=open('myfile.txt', 'rb').read(),
key_provider=kms_key_provider
)
# S3にアップロード(暗号化済み)
s3 = boto3.client('s3')
s3.put_object(Bucket='my-bucket', Key='myfile.txt', Body=ciphertext)
暗号化の強制
S3バケットに非暗号化アップロードを禁止するポリシー:
// SSE-KMSでない場合にアップロードを拒否
{
"Statement": [{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "aws:kms"
}
}
}]
}
// 特定のKMSキー以外での暗号化を拒否
{
"Statement": [{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"StringNotEqualsIfExists": {
"s3:x-amz-server-side-encryption-aws-kms-key-id":
"arn:aws:kms:ap-northeast-1:123456789012:key/xxx"
}
}
}]
}
試験頻出ポイント
| 問題パターン | 回答 |
|---|---|
| 監査・コンプライアンス要件でキー使用履歴が必要 | SSE-KMS(CloudTrail連携) |
| KMSコストを最小化しつつSSE-KMSを使う | S3 Bucket Keyを有効化 |
| AWSに鍵を渡したくない | SSE-C またはクライアントサイド |
| 最もシンプルな暗号化 | SSE-S3(デフォルト) |
| HTTPSなしでのSSE-C | 自動でリクエスト拒否 |
| 二重暗号化が規制で必要 | DSSE-KMS |
まとめ
S3暗号化の選択は「誰が鍵を管理するか」と「監査要件があるか」で決まる。特にSSE-KMSはKMSコストとCloudTrail監査のトレードオフを理解することが重要だ。S3 Bucket Keyは大規模利用時のコスト対策として必ず有効化を検討する。