概要
Amazon S3 に保存するデータは、2023 年 1 月 5 日以降、何も設定しなくても自動で暗号化されています。ただし、このとき使われる鍵は Amazon S3 が管理する鍵です。「暗号化キーは自社で保管し、AWS には預けない」という要件があると、既定のままでは満たせません。
S3 の暗号化は、鍵を誰が持ち、誰が暗号化の処理をするかで選び方が決まります。S3 に任せる SSE-S3、AWS KMS のキーを使う SSE-KMS、リクエストのたびに自分の鍵を渡す SSE-C、アップロードの前に手元で暗号化するクライアント側の暗号化です。このうち、自分の鍵を AWS に保存させずに済むのは SSE-C とクライアント側の暗号化です。
さらに 2026 年 4 月から、新しく作る汎用バケットでは SSE-C が既定でブロックされるようになりました。SSE-C を使うには、バケットごとに明示的に許可する必要があります。
この記事では、4 つの方式を鍵の持ち主で整理し、SSE-C の仕組みと制約を確認します。実践では、新しいバケットで SSE-C が拒否されることを確かめてから許可し、SSE-C・SSE-KMS・クライアント側の暗号化でオブジェクトを保存して違いを見比べます。

クラウドおさるバナナ倉庫の鍵を、倉庫番に預けるか、自分の懐に入れておくか。今日は「鍵を誰が持つか」で S3 の暗号化を選び分けるでござるよ。
この記事のメリット
- SSE-S3・SSE-KMS・SSE-C・クライアント側の暗号化を、鍵の持ち主と暗号化の処理をする場所で区別できるようになる
- 「自社で管理する鍵で暗号化したい」という要件に合う方式を選べるようになる
- SSE-C の仕組み(S3 は鍵を保存しない、HTTPS が必須、鍵を失うとデータも失う)を説明できるようになる
- 2026 年 4 月からの、新しいバケットで SSE-C が既定でブロックされる設定と、その解除方法が分かる
- CloudShell から SSE-C とクライアント側の暗号化でオブジェクトを保存・取得する手順が分かる
執筆者とキャラクター紹介
執筆者:土肥(とひ)
株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。


クラウドおさる



はじめましてでござる。弊猿はクラウドおさる。IT インフラが異常に発達した猿山から、雲に乗って地上の AWS を学びに降りてきたのでござる。



基礎編や Cloud Practitioner の記事では、とひさんに素朴な疑問をぶつける役でござるな。Security - Specialty などの記事では、要所でワンポイントや注意点をひとこと添えるでござる。



猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。
技術解説
4 つの方式と鍵の持ち主
S3 で保管時の暗号化をする方法は、S3 がサーバー側で暗号化する「サーバー側の暗号化」と、アップロードの前に自分で暗号化する「クライアント側の暗号化」に分かれます。サーバー側の暗号化はさらに、鍵の扱いで方式が分かれます。
| 方式 | 鍵を管理するのは | 暗号化・復号の処理 | 特徴 |
|---|---|---|---|
| SSE-S3 | Amazon S3 | S3 | すべてのバケットの既定。オブジェクトごとに一意のキーで暗号化し、そのキーを定期的にローテーションされるルートキーで暗号化する |
| SSE-KMS | AWS KMS(カスタマーマネージドキーか AWS マネージドキー) | S3(キーは KMS) | キーポリシーで使える人を絞れ、キーの使用が CloudTrail に残る |
| SSE-C | お客様 | S3 | リクエストのたびに鍵を渡す。S3 は鍵を保存しない |
| クライアント側の暗号化 | お客様 | お客様(アップロード前) | S3 は暗号化済みのデータを受け取るだけで、暗号化にも復号にも関与しない |
サーバー側の暗号化には、KMS のキーと S3 のキーで 2 回暗号化する DSSE-KMS もあります。サーバー側の暗号化の方式は相互に排他的で、1 つのオブジェクトに 2 つを同時に適用することはできません。


「暗号化キーは自社で保管し、AWS に保存させない」という要件なら、選べるのは SSE-C と クライアント側の暗号化です。SSE-S3 と SSE-KMS は、鍵を AWS 側で管理する方式です。



倉庫番に鍵ごと任せるのが SSE-S3、長老会の鍵箱に預けて使うたびに記帳されるのが SSE-KMS でござる。鍵を懐に入れたまま、毎回倉庫番に手渡して開けてもらうのが SSE-C、倉庫に入れる前に自分で箱に鍵をかけるのがクライアント側の暗号化でござるな。
SSE-C の仕組み
SSE-C では、オブジェクトをアップロードするリクエストに鍵を付けて送ります。S3 はその鍵で AES-256 の暗号化をしてから、鍵をメモリから消します。
| 項目 | 内容 |
|---|---|
| 渡すもの | 3 つのリクエストヘッダー。アルゴリズム(AES256)、base64 でエンコードした 256 ビットの鍵、鍵の MD5 ダイジェスト |
| 鍵の保存 | S3 は鍵を保存しない。以降のリクエストを検証するために、ランダムなソルトを付けた鍵の HMAC 値だけを保存する |
| 取得 | オブジェクトを取得するときも、同じ鍵をリクエストで渡す必要がある |
| 通信 | SSE-C のヘッダーを付けるリクエストは HTTPS が必須 |
| コンソール | S3 コンソールでは SSE-C を使えない。AWS CLI・SDK・REST API で使う |
S3 が保存している HMAC 値からは、鍵も、オブジェクトの中身も取り出せません。鍵を失うと、そのオブジェクトも失われます。鍵の保管と、どのオブジェクトにどの鍵を使ったかの管理は、すべて利用者の責任になります。
2026 年 4 月からの既定: 新しいバケットでは SSE-C がブロックされる
2026 年 4 月に、汎用バケットの新しい既定のセキュリティ設定が適用されました。
- 新しく作る汎用バケットでは、SSE-C が既定でブロックされる(中東(バーレーン)と中東(UAE)リージョンを除く)
- SSE-C で暗号化したオブジェクトが 1 つもなかったアカウントでは、既存のバケットでも SSE-C がブロックされた
- ブロック中のバケットに SSE-C を指定した書き込み(
PutObject・CopyObject・PostObject・マルチパートアップロード・レプリケーション)は、HTTP 403 のAccessDeniedで拒否される - ブロックしても、すでに SSE-C で保存したオブジェクトは読み取れる
SSE-C を使うには、バケットのデフォルトの暗号化の設定で「ブロックされた暗号化タイプ」から SSE-C を外します。API では PutBucketEncryption で BlockedEncryptionTypes を NONE にします。



SSE-C は鍵を失えばバナナも取り出せなくなる方式でござる。だからこそ、新しいバケットでは最初から閉じてあるのでござるな。使うバケットだけ、わざと開けるのが今のやり方でござるぞ。
クライアント側の暗号化
クライアント側の暗号化では、データを手元で暗号化してから S3 に送ります。S3 は暗号化済みのデータを受け取るだけなので、オブジェクトの中身は AWS を含む第三者に公開されません。
AWS は、PutObject と GetObject のついでに暗号化と復号をしてくれる Amazon S3 暗号化クライアントを提供しています。S3 から見ると普通のオブジェクトなので、バケットの既定の SSE-S3 も重ねて適用されます。
実践
新しい汎用バケットで SSE-C が拒否されることを確かめてから、SSE-C を許可します。CloudShell から SSE-C・SSE-KMS・クライアント側の暗号化でオブジェクトを保存し、取得のしかたとコンソールの表示を見比べます。最後に SSE-C をブロックし直し、既存のオブジェクトは読めることを確かめます。
前提条件
- リージョン:
ap-northeast-1(東京) - S3 の操作権限(バケットの暗号化設定の変更
s3:PutEncryptionConfigurationを含む)を持つ IAM ユーザーまたはロールでコンソールにログイン済みであること - AWS CloudShell が使えること
事前に作成しておくリソースはありません。このハンズオンで作成するリソースは以下のとおりです。
| リソース種別 | リソース名 | 用途 |
|---|---|---|
| S3 汎用バケット | sse-lab-<任意の文字列> | 暗号化の方式を比べる(バケット名は世界で一意にする) |
| オブジェクト | ssec.txt / kms.txt / client.txt.enc | SSE-C・SSE-KMS・クライアント側の暗号化で保存したもの |
| 鍵ファイル(CloudShell 内) | ssec.key / client.pass | SSE-C の鍵と、クライアント側の暗号化のパスフレーズ |
手順 1: バケットを作り、SSE-C がブロックされていることを確かめる
AWS マネジメントコンソールにログインし、リージョンが ap-northeast-1(東京)であることを確認します。
上部の検索バーに S3 と入力し、「S3」を選択します。左側ナビゲーションの「汎用バケット」から「バケットを作成」をクリックし、バケット名に sse-lab-<任意の文字列> を入力します。その他の項目はデフォルトのままにして、「バケットを作成」をクリックします。
作成したバケットを開き、「プロパティ」タブの「デフォルトの暗号化」を確認します。暗号化タイプが「Amazon S3 マネージドキーを使用したサーバー側の暗号化 (SSE-S3)」になっており、「ブロックされた暗号化タイプ」に「お客様提供のキーによるサーバー側の暗号化 (SSE-C)」が表示されています。


手順 2: SSE-C でのアップロードが拒否されることを確かめる
コンソール上部の CloudShell アイコンから CloudShell を開き、次のコマンドを実行します。BUCKET には手順 1 で作ったバケット名を入れます。
BUCKET=sse-lab-<任意の文字列>
# SSE-C の鍵(256 ビット = 32 バイト)を作る
openssl rand 32 > ssec.key
echo "SSE-C で保存したファイル" > ssec.txt
aws s3 cp ssec.txt s3://$BUCKET/ssec.txt --sse-c AES256 --sse-c-key fileb://ssec.keyAccessDenied のエラーで拒否されることを確認します。エラーの後半には「because this bucket has blocked upload requests that specify Server Side Encryption with Customer provided keys (SSE-C)」と理由が表示されます。新しいバケットでは、SSE-C を指定した書き込みが既定でブロックされているためです。


手順 3: バケットで SSE-C を許可する
S3 コンソールに戻り、バケットの「プロパティ」タブの「デフォルトの暗号化」で「編集」をクリックします。
「デフォルトの暗号化を編集」の画面の「ブロックされる暗号化タイプ」で、「SSE-C (顧客提供のキーによるサーバー側の暗号化)」のチェックを外します(手順 1 で見た「ブロックされた暗号化タイプ」と同じ項目で、編集画面では表記が少し違います)。暗号化タイプは SSE-S3 のままにして、「変更の保存」をクリックします。


手順 4: SSE-C で保存し、鍵がないと取得できないことを確かめる
CloudShell に戻り、同じアップロードをもう一度実行します。今度は成功します。
aws s3 cp ssec.txt s3://$BUCKET/ssec.txt --sse-c AES256 --sse-c-key fileb://ssec.key鍵を渡さずに取得すると、An error occurred (400) when calling the HeadObject operation: Bad Request のエラーで取得できません。
aws s3 cp s3://$BUCKET/ssec.txt -同じ鍵を渡すと取得できます。
aws s3 cp s3://$BUCKET/ssec.txt - --sse-c AES256 --sse-c-key fileb://ssec.key

手順 5: SSE-KMS とクライアント側の暗号化でも保存する
SSE-KMS(AWS マネージドキー aws/s3)で保存します。
echo "SSE-KMS で保存したファイル" > kms.txt
aws s3 cp kms.txt s3://$BUCKET/kms.txt --sse aws:kmsクライアント側の暗号化は、ここでは S3 暗号化クライアントの代わりに openssl で手元のファイルを暗号化してから、普通にアップロードします。
openssl rand -base64 32 > client.pass
echo "クライアント側で暗号化したファイル" > client.txt
openssl enc -aes-256-cbc -pbkdf2 -salt -in client.txt -out client.txt.enc -pass file:./client.pass
aws s3 cp client.txt.enc s3://$BUCKET/client.txt.encS3 コンソールでバケットを開き、3 つのオブジェクトが並んでいることを確認します。


kms.txt を開き、「プロパティ」タブの「サーバー側の暗号化設定」で、暗号化タイプが SSE-KMS で、AWS KMS キーが表示されていることを確認します。


ssec.txt を開くと、「サーバー側の暗号化設定」は「不明なエラー」と表示され、暗号化の設定を読み取れません。その下の「チェックサム」には「SSE-C で暗号化されたオブジェクト」と表示され、AWS CLI・AWS SDK・REST API を使うよう案内されます。SSE-C はコンソールでは使えないため、コンソールからこのオブジェクトの中身を開くこともできません。


手順 6: クライアント側で暗号化したデータを確かめる
CloudShell に戻り、client.txt.enc をそのまま取得します。S3 から返ってくるのは暗号化済みのデータなので、中身は読めません。手元のパスフレーズで復号すると、元の文字列に戻ります。
aws s3 cp s3://$BUCKET/client.txt.enc - | head -c 64 | od -c | head -3
aws s3 cp s3://$BUCKET/client.txt.enc - | openssl enc -d -aes-256-cbc -pbkdf2 -pass file:./client.pass

S3 はこのオブジェクトにも既定の SSE-S3 をかけていますが、その下の中身はすでに手元で暗号化されています。パスフレーズは S3 にも AWS にも渡していません。



SSE-C は「鍵を毎回手渡し」、クライアント側の暗号化は「箱に鍵をかけてから預ける」でござる。どちらも鍵は懐から出ていかないから、なくしたら弊猿にも開けられないのでござるな。
手順 7: SSE-C をブロックし直し、既存のオブジェクトは読めることを確かめる
S3 コンソールでバケットの「デフォルトの暗号化」の「編集」を開き、「SSE-C (顧客提供のキーによるサーバー側の暗号化)」に再びチェックを入れて「変更の保存」をクリックします。
CloudShell で、新しい SSE-C の書き込みと、既存のオブジェクトの取得を試します。
aws s3 cp ssec.txt s3://$BUCKET/ssec-2.txt --sse-c AES256 --sse-c-key fileb://ssec.key
aws s3 cp s3://$BUCKET/ssec.txt - --sse-c AES256 --sse-c-key fileb://ssec.key新しい書き込みは AccessDenied で拒否され、すでに SSE-C で保存した ssec.txt は鍵を渡せば取得できることを確認します。





「自社の鍵で」「AWS に鍵を保存させずに」と言われたら、SSE-C かクライアント側の暗号化でござる。KMS のカスタマーマネージドキーも自分で管理する鍵ではござるが、鍵そのものは KMS の中にあるので、取り違えやすいところでござるぞ。
まとめ
| 要件 | 選ぶもの |
|---|---|
| 特に要件はなく、暗号化されていればよい | SSE-S3(既定のまま) |
| 鍵を使える人をキーポリシーで絞り、使用を CloudTrail で追いたい | SSE-KMS |
| 自分の鍵を使い、AWS には保存させたくない。暗号化の処理は S3 に任せたい | SSE-C(バケットで SSE-C を許可する) |
| 自分の鍵を使い、暗号化も手元で済ませて、AWS に平文を渡したくない | クライアント側の暗号化 |
- 2023 年 1 月 5 日以降、S3 に新しくアップロードするオブジェクトは既定で SSE-S3 で暗号化される
- SSE-C では S3 は鍵を保存せず、ソルト付きの HMAC 値だけを持つ。取得のたびに同じ鍵が要り、鍵を失うとオブジェクトも失われる
- SSE-C のリクエストは HTTPS が必須で、S3 コンソールでは使えない
- 2026 年 4 月から、新しい汎用バケットでは SSE-C が既定でブロックされる。使うには「ブロックされた暗号化タイプ」から外す(
BlockedEncryptionTypesをNONE)。ブロック中の書き込みは 403AccessDeniedで拒否されるが、既存のオブジェクトは読める - クライアント側の暗号化では、S3 は暗号化済みのデータを受け取るだけで、暗号化にも復号にも関与しない
参照先
- サーバー側の暗号化によるデータの保護 – Amazon Simple Storage Service
- お客様が指定したキーによるサーバー側の暗号化 (SSE−C) の使用 – Amazon Simple Storage Service
- お客様が用意したキーによるサーバー側の暗号化 (SSE−C) の指定 – Amazon Simple Storage Service
- 汎用バケットの SSE-C のブロックまたはブロック解除 – Amazon Simple Storage Service
- 新しいバケットの SSE-C 設定に関するよくある質問 – Amazon Simple Storage Service
- クライアント側の暗号化を使用したデータの保護 – Amazon Simple Storage Service















