

# お客様が指定したキーによるサーバー側の暗号化 (SSE−C) の使用
<a name="ServerSideEncryptionCustomerKeys"></a>

サーバー側の暗号化は、保管時のデータ保護に関するものです。サーバー側の暗号化では、オブジェクトのメタデータではなく、オブジェクトデータのみが暗号化されます。汎用バケットでお客様が用意したキーでのサーバー側の暗号化 (SSE−C) を使用すると、独自の暗号化キーでデータを暗号化できます。リクエストの一部として用意された暗号化キーで、Amazon S3 は、ディスクに書き込む際のデータ暗号化と、オブジェクトにアクセスする際のデータ復号を管理します。したがって、データの暗号化と復号を実行するコードをお客様が管理する必要はありません。必要なことは、お客様が用意する暗号化キーを管理することだけです。

Amazon S3 の最新のユースケースのほとんどでは、Amazon S3 マネージドキーによるサーバー側の暗号化 (SSE-S3) や AWS KMS キーによるサーバー側の暗号化 (SSE-KMS) の柔軟性が欠けているため、SSE-C は使用されなくなりました。SSE-C では、SSE-C 暗号化データとやり取りするたびに暗号化キーを提供する必要があるため、S3 バケットからデータを読み取ってデータを操作しようとする他のユーザー、ロール、または AWS のサービスと SSE-C キーを共有することは実用的ではありません。AWS 全体で SSE-KMS が広範囲にサポートされているため、ほとんどの最新のワークロードでは SSE-KMS の柔軟性が不足しているため、SSE-C 暗号化を使用しません。SSE-KMS の詳細については、「[AWS KMS キーによるサーバー側の暗号化 (SSE-KMS) の使用](UsingKMSEncryption.md)」を参照してください。

バケットに書き込まれたオブジェクトに SSE-C 暗号化が使用されないようにするには、バケットのデフォルトの暗号化設定を変更するときに SSE-C 暗号化をブロックできます。汎用バケットに対して SSE-C がブロックされている場合、SSE-C 暗号化を指定する `PutObject`、`CopyObject`、`PostObject`、マルチパートアップロードまたはレプリケーションリクエストは `HTTP 403 AccessDenied` エラーで拒否されます。SSE-C のブロックの詳細については、「[汎用バケットの SSE-C のブロックまたはブロック解除](blocking-unblocking-s3-c-encryption-gpb.md)」を参照してください。

SSE-C の使用に追加料金はかかりません。ただし、SSE-C を設定および使用するためのリクエストには、標準の Amazon S3 リクエスト料金が発生します。料金については、「[Amazon S3 の料金](https://aws.amazon.com/s3/pricing/)」を参照してください。

**重要**  
2026 年 4 月以降、AWS はすべての新しいバケットについて、お客様が用意したキー (SSE-C) によるサーバー側の暗号化を無効にします。さらに、SSE-C 暗号化は、SSE-C 暗号化データを持たない AWS アカウントのすべての既存のバケットに対して無効になります。これらの変更により、SSE-C 暗号化を必要とする少数のアプリケーションは、バケットの作成後に [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) API を介して SSE-C の使用を意図的に有効にする必要があります。このような場合、自動化スクリプト、CloudFormation テンプレート、またはその他のインフラストラクチャ設定ツールを更新して、これらの設定を構成する必要がある場合があります。詳細については、[AWS ストレージブログ記事](https://aws.amazon.com/blogs/storage/advanced-notice-amazon-s3-to-disable-the-use-of-sse-c-encryption-by-default-for-all-new-buckets-and-select-existing-buckets-in-april-2026/)を参照してください。

## SSE-C を使用する前の考慮事項
<a name="considerations-before-using-sse-c"></a>
+ S3 は暗号化キーを保存しません。S3 から SSE-C 暗号化データをダウンロードするたびに、暗号化キーを指定する必要があります。
  + 使用した暗号化キーと暗号化したオブジェクトのマッピングは、お客様に管理していただきます。どのオブジェクトにどの暗号化キーを使用したかは、お客様が管理してください。これは、暗号化キーを紛失した場合、オブジェクトも失われることを意味します。
  + クライアント側の暗号化キーはお客様が管理するため、キーの更新など、クライアント側での追加の安全対策はお客様に管理していただきます。
  + この設計により、データを操作する他のユーザー、ロール、または AWS のサービスと SSE-C キーを共有することが困難になる可能性があります。AWS 全体で SSE-KMS が広範囲にサポートされているため、ほとんどの最新のワークロードでは SSE-KMS の柔軟性が不足しているため、SSE-C を使用しません。SSE-KMS の詳細については、「[AWS KMS キーによるサーバー側の暗号化の使用 (SSE-KMS)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html)」を参照してください。
  + つまり、SSE-C で暗号化されたオブジェクトは、AWS マネージドサービスによってネイティブに復号することはできません。
+ リクエストで SSE-C ヘッダーを指定するときは、HTTPS を使用する必要があります。
  + SSE−C を使用する場合、Amazon S3 は HTTP 経由で行われたリクエストをすべて拒否します。セキュリティ上の考慮事項として、誤って HTTP で送信されたキーは漏洩したと見なすことをお勧めします。キーを破棄して、必要に応じて更新してください。
+ バケットのバージョニングが有効になっている場合、アップロードする各オブジェクトバージョンに、独自の暗号化キーを使用できます。どのオブジェクトバージョンにどの暗号化キーを使用したかは、お客様が管理してください。
+ SSE-C は Amazon S3 コンソールではサポートされていません。Amazon S3 コンソールを使用してオブジェクトをアップロードし、SSE-C 暗号化を指定することはできません。また、コンソールを使用して、SSE-C を使用して保存されている既存のオブジェクトを更新すること (ストレージクラスの変更やメタデータの追加など) もできません。

**Topics**
+ [

## SSE-C を使用する前の考慮事項
](#considerations-before-using-sse-c)
+ [

# お客様が用意したキーによるサーバー側の暗号化 (SSE−C) の指定
](specifying-s3-c-encryption.md)
+ [

# 汎用バケットの SSE-C のブロックまたはブロック解除
](blocking-unblocking-s3-c-encryption-gpb.md)
+ [

# 新しいバケットの SSE-C 設定に関するよくある質問
](default-s3-c-encryption-setting-faq.md)

# お客様が用意したキーによるサーバー側の暗号化 (SSE−C) の指定
<a name="specifying-s3-c-encryption"></a>

お客様が用意したキーによるサーバー側の暗号化 (SSE-C) を使用するには、まず SSE-C が Amazon S3 汎用バケットのデフォルトの暗号化設定でブロックされた暗号化タイプではないことを確認してください。ブロックされている場合は、バケットのデフォルトの暗号化設定を更新することで、この暗号化タイプを有効にできます。次に、必要なヘッダーを渡すことで、アップロードリクエストで SSE-C を使用できます。「[SSE-C を使用したデータの書き込みをサポートする Amazon S3 アクション](#amazon-s3-actions-that-support-writing-data-with-sse-c)」を参照し、必ず [SSE-C オブジェクトの暗号化および復号リクエストに必要な S3 API ヘッダー](#s3-api-headers-required-for-sse-c-object-encryption-and-decryption-requests) を含めてください。

SSE-C を指定してオブジェクトをアップロードする場合、Amazon S3 はお客様が用意した暗号化キーを使用してデータに AES−256 暗号化を適用します。その後、Amazon S3 はメモリから暗号化キーを削除します。オブジェクトを取得するときは、リクエストの中で同じ暗号化キーを指定する必要があります。Amazon S3 では、最初に指定された暗号化キーが一致することを確認した後、オブジェクトを復号してから、オブジェクトデータを返します。

SSE-C を使用する前に、「[SSE-C を使用する前の考慮事項](ServerSideEncryptionCustomerKeys.md#considerations-before-using-sse-c)」を確認してください。

**注記**  
Amazon S3 では、お客様が用意した暗号化キーを保存しません。代わりに、以降のリクエストを検証するために、ランダムな SALT 値が付加された暗号化キーの Hash-based Message Authentication Code (HMAC) 値が保存されます。SALT 値が付加された HMAC 値を使用して、暗号化キーの値を求めたり、暗号化されたオブジェクトの内容を復号したりすることはできません。これは、暗号化キーを紛失した場合、オブジェクトが失われることを意味します。

**Topics**
+ [

## SSE-C アクションと必要なヘッダー
](#sse-c-actions-and-required-headers)
+ [

## SSE-C 暗号化を適用するためのバケットポリシーの例
](#example-bucket-policy-to-enforce-sse-c-encryption)
+ [

## 署名済み URL および SSE−C
](#ssec-and-presignedurl)
+ [

## SSE-C によるリクエストの作成
](#making-requests-with-sse-c)
+ [

## REST API の使用
](#using-rest-api-sse-c)
+ [

## AWS SDK を使用して PUT、GET、Head、および Copy オペレーションの SSE−C を指定する
](#sse-c-using-sdks)
+ [

## AWS SDK を使用してマルチパートアップロードの SSE−C を指定する
](#sse-c-using-sdks-multipart-uploads)

## SSE-C アクションと必要なヘッダー
<a name="sse-c-actions-and-required-headers"></a>

サポートされている S3 API で SSE-C を指定するには、特定のリクエストパラメータを渡す必要があります。

**注記**  
Amazon S3 の `PutBucketEncryption` API は、バケットのデフォルトのサーバー側の暗号化を設定するために使用されます。ただし、`PutBucketEncryption` はバケットのデフォルトの暗号化方法としての SSE-C の有効化をサポートしていません。SSE-C はオブジェクトレベルの暗号化方法で、オブジェクトのアップロードまたはダウンロードリクエストごとに暗号化キーを Amazon S3 に提供します。Amazon S3 はこのキーを使用して、リクエスト中にオブジェクトを暗号化または復号し、キーを破棄します。つまり、SSE-C はデフォルトのバケット設定としてではなく、オブジェクトごとに有効になります。

### SSE-C を使用したデータの書き込みをサポートする Amazon S3 アクション
<a name="amazon-s3-actions-that-support-writing-data-with-sse-c"></a>

次の API オペレーションまたはアクションを使用して、汎用バケットにオブジェクトを書き込むときに、お客様が用意したキー (SSE-C) によるサーバー側の暗号化をリクエストできます。
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html)

**注記**  
S3 レプリケーションは、SSE-C で暗号化されたオブジェクトをサポートします。暗号化されたオブジェクトのレプリケーションの詳細については、「[暗号化されたオブジェクトのレプリケート (SSE-S3、SSE-KMS、DSSE-KMS、SSE-C)](replication-config-for-kms-objects.md)」を参照してください。

### SSE-C オブジェクトの暗号化および復号リクエストに必要な S3 API ヘッダー
<a name="s3-api-headers-required-for-sse-c-object-encryption-and-decryption-requests"></a>

SSE-C でオブジェクトを暗号化または復号するには、次の 3 つの API ヘッダーを指定する必要があります。
+ `x-amz-server-side-encryption-customer-algorithm` 暗号化アルゴリズムを指定するには、このヘッダーを使用します。ヘッダーの値は AES256 である必要があります。
+ `x-amz-server-side-encryption-customer-key` Amazon S3 でデータを暗号化または復号するために使用する base64 でエンコードされた 256 ビットの暗号化キーを指定するには、このヘッダーを使用します。
+ `x-amz-server-side-encryption-customer-key-MD5` RFC 1321 に従って、暗号化キーの base64 エンコードされた 128 ビット MD5 ダイジェストを指定するには、このヘッダーを使用します。Amazon S3 では、このヘッダーを使用してメッセージの整合性を調べて、送信された暗号化キーにエラーがないことを確認します。

### SSE-C で暗号化されたソースオブジェクトをコピーするリクエストに必要な S3 API ヘッダー
<a name="s3-api-headers-required-for-requests-to-copy-source-objects-encrypted-with-sse-c"></a>

SSE-C で暗号化されたソースオブジェクトをコピーするには、次の 3 つの API ヘッダーを指定する必要があります。
+ `x-amz-copy-source-server-side-encryption-customer-algorithm` Amazon S3 でソースオブジェクトを復号するために使用するアルゴリズムを指定するには、このヘッダーを含めます。この値は、AES256 である必要があります。
+ `x-amz-copy-source-server-side-encryption-customer-key` Amazon S3 でソースオブジェクトを復号するために使用する base64 でエンコードされた暗号化キーを指定するには、このヘッダーを含めます。この暗号化キーは、Amazon S3 でソースオブジェクトを作成したときに指定したキーであることが必要です。それ以外の場合、Amazon S3 でオブジェクトを復号できません。
+ `x-amz-copy-source-server-side-encryption-customer-key-MD5` RFC 1321 に従って、暗号化キーの base64 エンコードされた 128 ビット MD5 ダイジェストを指定するには、このヘッダーを含めます。

## SSE-C 暗号化を適用するためのバケットポリシーの例
<a name="example-bucket-policy-to-enforce-sse-c-encryption"></a>

Amazon S3 バケットに書き込まれるすべてのオブジェクトに対して SSE-C を要求するには、バケットポリシーを使用できます。例えば、次のバケットポリシーは、SSE-C を要求する `x-amz-server-side-encryption-customer-algorithm` ヘッダーを含まないすべてのリクエストに対して、オブジェクトのアップロード (`s3:PutObject`) 許可を拒否します。

```
{  
"Version":"2012-10-17",		 	 	                      
    "Id": "PutObjectPolicy",  
    "Statement": [  
        {  
"Sid": "RequireSSECObjectUploads",  
            "Effect": "Deny",  
            "Principal": "*",  
            "Action": "s3:PutObject",  
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*",  
            "Condition": {  
            "Null": {  
              "s3:x-amz-server-side-encryption-customer-algorithm": "true"  
                }  
            }  
        }  
    ]  
}
```

**重要**  
バケットポリシーを使用して `s3:PutObject` に対する SSE-C を要求する場合は、すべてのマルチパートアップロードリクエスト (CreateMultiPartUpload、UploadPart、CompleteMultipartUpload) に `x-amz-server-side-encryption-customer-algorithm` ヘッダーを含める必要があります。

## 署名済み URL および SSE−C
<a name="ssec-and-presignedurl"></a>

新しいオブジェクトのアップロード、既存のオブジェクトやオブジェクトメタデータの取得などのオペレーションに使用できる署名付き URL を生成できます。署名付き URL では、次のように SSE−C がサポートされます。
+ 署名付き URL を作成するときに、署名の計算で `x-amz-server-side-encryption-customer-algorithm` ヘッダーを使用してアルゴリズムを指定する必要があります。
+ 署名付き URL を使用して新しいオブジェクトをアップロードするとき、既存のオブジェクトを取得するとき、またはオブジェクトメタデータのみを取得するときに、クライアントアプリケーションのリクエストですべての暗号化ヘッダーを指定する必要があります。
**注記**  
SSE−C 以外のオブジェクトでは、署名付き URL を生成し、その URL をブラウザに直接貼り付けることで、データにアクセスできます。  
ただし、これは SSE−C オブジェクトには行えません。署名付き URL に加えて SSE−C オブジェクトに固有の HTTP ヘッダーも含める必要があります。したがって、SSE−C オブジェクトの署名付き URL はプログラムでのみ使用できます。

署名付き URL の詳細については、「 」を参照してください[署名付き URL を使用したオブジェクトのダウンロードおよびアップロード](using-presigned-url.md)

## SSE-C によるリクエストの作成
<a name="making-requests-with-sse-c"></a>

 REST API を使用したオブジェクトの作成時に、お客様が用意したキー (SSE−C) を使用してサーバー側の暗号化を指定できます。SSE−C を使用する場合は、[SSE-C で暗号化されたソースオブジェクトをコピーするリクエストに必要な S3 API ヘッダー](#s3-api-headers-required-for-requests-to-copy-source-objects-encrypted-with-sse-c) を使用して暗号化キー情報を指定する必要があります。AWS SDK ラッパーライブラリを使用して、これらのヘッダーをリクエストに追加できます。必要に応じて、アプリケーションから直接 Amazon S3 REST API を呼び出すことができます。

**重要**  
お客様が用意したキーによるサーバー側の暗号化 (SSE-C) を指定する前に、汎用バケットで SSE-C 暗号化がブロックされていないことを確認してください。詳細については、「[汎用バケットの SSE-C のブロックまたはブロック解除](blocking-unblocking-s3-c-encryption-gpb.md)」を参照してください。

**注記**  
Amazon S3 コンソールを使用してオブジェクトをアップロードしたり SSE−C をリクエストしたりすることはできません。また、SSE−C を使用して保存されている既存のオブジェクトを更新すること (ストレージクラスの変更やメタデータの追加など) もできません。詳細については、「[SSE-C オブジェクトの暗号化および復号リクエストに必要な S3 API ヘッダー](#s3-api-headers-required-for-sse-c-object-encryption-and-decryption-requests)」を参照してください。

## REST API の使用
<a name="using-rest-api-sse-c"></a>

### SSE−C をサポートする Amazon S3 REST API
<a name="sse-c-supported-apis"></a>

次の Amazon S3 API は、お客様が用意した暗号化キー (SSE−C) を使用したサーバー側の暗号化をサポートします。
+ **GET オペレーション** — GET API ([GET Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html) を参照) を使用してオブジェクトを取得するときに、このリクエストヘッダーを指定できます。
+ **HEAD オペレーション** — HEAD API ([HEAD Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectHEAD.html) を参照) を使用してオブジェクトメタデータを取得するには、これらのリクエストヘッダーを指定できます。
+ **PUT オペレーション** — PUT API ([PUT Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html) を参照) を使用してデータをアップロードするときに、これらのリクエストヘッダーを指定できます。
+ **マルチパートアップロード** — マルチパートアップロード API を使用して大きいオブジェクトをアップロードするときに、これらのヘッダーを指定できます。これらのヘッダーは、開始リクエスト ([Initiate Multipart Upload](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html) を参照) と、後続の各パートのアップロードリクエスト ([Upload Part](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPart.html) または [UploadPartCopy](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html) を参照) で指定します。各パートのアップロードリクエストでは、暗号化情報がマルチパートアップロードの開始リクエストで指定した情報と同じである必要があります。
+ **POST オペレーション** — POST オペレーションを使用してオブジェクトをアップロードする場合は ([POST Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) を参照)、リクエストヘッダーの代わりに、フォームフィールドで同じ情報を指定します。
+ **Copy オペレーション** — オブジェクトをコピーする場合 ([CopyObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) を参照)、ソースオブジェクトとターゲットオブジェクトがあります。
  + ターゲットオブジェクトの暗号化タイプを指定する場合は、`x-amz-server-side-encryption ` リクエストヘッダーを指定する必要があります。
  + SSE−C を使用してターゲットオブジェクトを暗号化する場合は、S3 API [SSE-C オブジェクトの暗号化および復号リクエストに必要な S3 API ヘッダー](#s3-api-headers-required-for-sse-c-object-encryption-and-decryption-requests) を使用して暗号化情報を指定する必要があります。
  + ソースオブジェクトが SSE−C を使用して暗号化されている場合は、S3 API ヘッダー [SSE-C で暗号化されたソースオブジェクトをコピーするリクエストに必要な S3 API ヘッダー](#s3-api-headers-required-for-requests-to-copy-source-objects-encrypted-with-sse-c) を使用して暗号化キー情報を指定する必要があります。

## AWS SDK を使用して PUT、GET、Head、および Copy オペレーションの SSE−C を指定する
<a name="sse-c-using-sdks"></a>

次の例では、お客様が用意したキーによるサーバー側の暗号化 (SSE−C) をオブジェクト用にリクエストする方法を示します。この例では、次の操作を実行します。各オペレーションでは、SSE−C 関連ヘッダーをリクエストで指定する方法を示します。
+ **Put object** — オブジェクトをアップロードし、顧客が用意した暗号キーによるサーバー側の暗号化をリクエストします。
+ **Get object** — 前のステップでアップロードしたオブジェクトをダウンロードします。リクエストでは、オブジェクトのアップロード時に指定したのと同じ暗号化情報を提供します。Amazon S3 は、オブジェクトを復号して返すために、この情報を必要とします。
+ **Get object metadata** — オブジェクトのメタデータを取得します。オブジェクトの作成時に使用したのと同じ暗号化情報を指定します。
+ **Copy object** — 以前にアップロードしたオブジェクトのコピーを作成します。ソースオブジェクトは SSE−C を使用して保存されるため、コピーリクエストで暗号化情報を指定する必要があります。デフォルトでは、明示的にリクエストした場合に限り、Amazon S3 はオブジェクトのコピーを暗号化します。この例では、オブジェクトの暗号化されたコピーを保存するように Amazon S3 に指示します。

------
#### [ Java ]

**注記**  
この例では、1 つのオペレーションでオブジェクトをアップロードする方法を示します。マルチパートアップロード API を使用して大きなオブジェクトをアップロードする場合は、この例に示したのと同じ方法で暗号化情報を指定します。AWS SDK for Java を使用するマルチパートアップロードの例については、[マルチパートアップロードを使用したオブジェクトのアップロード](mpu-upload-object.md) を参照してください。

必要な暗号化情報を追加するには、リクエストに `SSECustomerKey` を含めます。`SSECustomerKey` クラスの詳細については、REST API」セクションを参照してください。

作業サンプルの作成およびテストの手順については、「AWS SDK for Java のデベロッパーガイド」の「[使用開始](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/getting-started.html)」を参照してください。

**Example**  

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;

import javax.crypto.KeyGenerator;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class ServerSideEncryptionUsingClientSideEncryptionKey {
    private static SSECustomerKey SSE_KEY;
    private static AmazonS3 S3_CLIENT;
    private static KeyGenerator KEY_GENERATOR;

    public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
        Regions clientRegion = Regions.DEFAULT_REGION;
        String bucketName = "*** Bucket name ***";
        String keyName = "*** Key name ***";
        String uploadFileName = "*** File path ***";
        String targetKeyName = "*** Target key name ***";

        // Create an encryption key.
        KEY_GENERATOR = KeyGenerator.getInstance("AES");
        KEY_GENERATOR.init(256, new SecureRandom());
        SSE_KEY = new SSECustomerKey(KEY_GENERATOR.generateKey());

        try {
            S3_CLIENT = AmazonS3ClientBuilder.standard()
                    .withCredentials(new ProfileCredentialsProvider())
                    .withRegion(clientRegion)
                    .build();

            // Upload an object.
            uploadObject(bucketName, keyName, new File(uploadFileName));

            // Download the object.
            downloadObject(bucketName, keyName);

            // Verify that the object is properly encrypted by attempting to retrieve it
            // using the encryption key.
            retrieveObjectMetadata(bucketName, keyName);

            // Copy the object into a new object that also uses SSE-C.
            copyObject(bucketName, keyName, targetKeyName);
        } catch (AmazonServiceException e) {
            // The call was transmitted successfully, but Amazon S3 couldn't process
            // it, so it returned an error response.
            e.printStackTrace();
        } catch (SdkClientException e) {
            // Amazon S3 couldn't be contacted for a response, or the client
            // couldn't parse the response from Amazon S3.
            e.printStackTrace();
        }
    }

    private static void uploadObject(String bucketName, String keyName, File file) {
        PutObjectRequest putRequest = new PutObjectRequest(bucketName, keyName, file).withSSECustomerKey(SSE_KEY);
        S3_CLIENT.putObject(putRequest);
        System.out.println("Object uploaded");
    }

    private static void downloadObject(String bucketName, String keyName) throws IOException {
        GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, keyName).withSSECustomerKey(SSE_KEY);
        S3Object object = S3_CLIENT.getObject(getObjectRequest);

        System.out.println("Object content: ");
        displayTextInputStream(object.getObjectContent());
    }

    private static void retrieveObjectMetadata(String bucketName, String keyName) {
        GetObjectMetadataRequest getMetadataRequest = new GetObjectMetadataRequest(bucketName, keyName)
                .withSSECustomerKey(SSE_KEY);
        ObjectMetadata objectMetadata = S3_CLIENT.getObjectMetadata(getMetadataRequest);
        System.out.println("Metadata retrieved. Object size: " + objectMetadata.getContentLength());
    }

    private static void copyObject(String bucketName, String keyName, String targetKeyName)
            throws NoSuchAlgorithmException {
        // Create a new encryption key for target so that the target is saved using
        // SSE-C.
        SSECustomerKey newSSEKey = new SSECustomerKey(KEY_GENERATOR.generateKey());

        CopyObjectRequest copyRequest = new CopyObjectRequest(bucketName, keyName, bucketName, targetKeyName)
                .withSourceSSECustomerKey(SSE_KEY)
                .withDestinationSSECustomerKey(newSSEKey);

        S3_CLIENT.copyObject(copyRequest);
        System.out.println("Object copied");
    }

    private static void displayTextInputStream(S3ObjectInputStream input) throws IOException {
        // Read one line at a time from the input stream and display each line.
        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
        System.out.println();
    }
}
```

------
#### [ .NET ]

**注記**  
マルチパートアップロード API を使用した大きなオブジェクトのアップロードの例については、[マルチパートアップロードを使用したオブジェクトのアップロード](mpu-upload-object.md) および [AWS SDK の使用 (低レベル API)](mpu-upload-object.md#mpu-upload-low-level) を参照してください。

コード例を設定および実行する方法の詳細については、「*AWS SDK for .NET デベロッパーガイド*」の「[AWS SDK for .NET の開始方法](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-setup.html)」 を参照してください。

**Example**  

```
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Threading.Tasks;

namespace Amazon.DocSamples.S3
{
    class SSEClientEncryptionKeyObjectOperationsTest
    {
        private const string bucketName = "*** bucket name ***"; 
        private const string keyName = "*** key name for new object created ***"; 
        private const string copyTargetKeyName = "*** key name for object copy ***";
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 client;

        public static void Main()
        {
            client = new AmazonS3Client(bucketRegion);
            ObjectOpsUsingClientEncryptionKeyAsync().Wait();
        }
        private static async Task ObjectOpsUsingClientEncryptionKeyAsync()
        {
            try
            {
                // Create an encryption key.
                Aes aesEncryption = Aes.Create();
                aesEncryption.KeySize = 256;
                aesEncryption.GenerateKey();
                string base64Key = Convert.ToBase64String(aesEncryption.Key);

                // 1. Upload the object.
                PutObjectRequest putObjectRequest = await UploadObjectAsync(base64Key);
                // 2. Download the object and verify that its contents matches what you uploaded.
                await DownloadObjectAsync(base64Key, putObjectRequest);
                // 3. Get object metadata and verify that the object uses AES-256 encryption.
                await GetObjectMetadataAsync(base64Key);
                // 4. Copy both the source and target objects using server-side encryption with 
                //    a customer-provided encryption key.
                await CopyObjectAsync(aesEncryption, base64Key);
            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine("Error encountered ***. Message:'{0}' when writing an object", e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
            }
        }

        private static async Task<PutObjectRequest> UploadObjectAsync(string base64Key)
        {
            PutObjectRequest putObjectRequest = new PutObjectRequest
            {
                BucketName = bucketName,
                Key = keyName,
                ContentBody = "sample text",
                ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                ServerSideEncryptionCustomerProvidedKey = base64Key
            };
            PutObjectResponse putObjectResponse = await client.PutObjectAsync(putObjectRequest);
            return putObjectRequest;
        }
        private static async Task DownloadObjectAsync(string base64Key, PutObjectRequest putObjectRequest)
        {
            GetObjectRequest getObjectRequest = new GetObjectRequest
            {
                BucketName = bucketName,
                Key = keyName,
                // Provide encryption information for the object stored in Amazon S3.
                ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                ServerSideEncryptionCustomerProvidedKey = base64Key
            };

            using (GetObjectResponse getResponse = await client.GetObjectAsync(getObjectRequest))
            using (StreamReader reader = new StreamReader(getResponse.ResponseStream))
            {
                string content = reader.ReadToEnd();
                if (String.Compare(putObjectRequest.ContentBody, content) == 0)
                    Console.WriteLine("Object content is same as we uploaded");
                else
                    Console.WriteLine("Error...Object content is not same.");

                if (getResponse.ServerSideEncryptionCustomerMethod == ServerSideEncryptionCustomerMethod.AES256)
                    Console.WriteLine("Object encryption method is AES256, same as we set");
                else
                    Console.WriteLine("Error...Object encryption method is not the same as AES256 we set");

                // Assert.AreEqual(putObjectRequest.ContentBody, content);
                // Assert.AreEqual(ServerSideEncryptionCustomerMethod.AES256, getResponse.ServerSideEncryptionCustomerMethod);
            }
        }
        private static async Task GetObjectMetadataAsync(string base64Key)
        {
            GetObjectMetadataRequest getObjectMetadataRequest = new GetObjectMetadataRequest
            {
                BucketName = bucketName,
                Key = keyName,

                // The object stored in Amazon S3 is encrypted, so provide the necessary encryption information.
                ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                ServerSideEncryptionCustomerProvidedKey = base64Key
            };

            GetObjectMetadataResponse getObjectMetadataResponse = await client.GetObjectMetadataAsync(getObjectMetadataRequest);
            Console.WriteLine("The object metadata show encryption method used is: {0}", getObjectMetadataResponse.ServerSideEncryptionCustomerMethod);
            // Assert.AreEqual(ServerSideEncryptionCustomerMethod.AES256, getObjectMetadataResponse.ServerSideEncryptionCustomerMethod);
        }
        private static async Task CopyObjectAsync(Aes aesEncryption, string base64Key)
        {
            aesEncryption.GenerateKey();
            string copyBase64Key = Convert.ToBase64String(aesEncryption.Key);

            CopyObjectRequest copyRequest = new CopyObjectRequest
            {
                SourceBucket = bucketName,
                SourceKey = keyName,
                DestinationBucket = bucketName,
                DestinationKey = copyTargetKeyName,
                // Information about the source object's encryption.
                CopySourceServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                CopySourceServerSideEncryptionCustomerProvidedKey = base64Key,
                // Information about the target object's encryption.
                ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                ServerSideEncryptionCustomerProvidedKey = copyBase64Key
            };
            await client.CopyObjectAsync(copyRequest);
        }
    }
}
```

------

## AWS SDK を使用してマルチパートアップロードの SSE−C を指定する
<a name="sse-c-using-sdks-multipart-uploads"></a>

前のセクションの例では、PUT、GET、Head、および COPY オペレーションで、お客様が用意したキーによるサーバー側の暗号化 (SSE−C) をリクエストする方法を示しています。このセクションでは、SSE−C をサポートするその他の Amazon S3 API について説明します。

------
#### [ Java ]

大きなオブジェクトをアップロードするために、マルチパートアップロード API を使用できます。詳細については、「[Amazon S3 でのマルチパートアップロードを使用したオブジェクトのアップロードとコピー](mpuoverview.md)」を参照してください。高レベル API または低レベル API を使用して、大きなオブジェクトをアップロードできます。これらの API は、リクエストでの暗号化関連のヘッダーをサポートします。
+ 高レベルの `TransferManager` API を使用する場合は、`PutObjectRequest` で暗号化専用のヘッダーを指定します。詳細については、「[マルチパートアップロードを使用したオブジェクトのアップロード](mpu-upload-object.md)」を参照してください。
+ 低レベル API を使用する場合は、暗号化関連情報を `InitiateMultipartUploadRequest` で指定し、続けて各 `UploadPartRequest` で同じ暗号化情報を指定します。`CompleteMultipartUploadRequest` で暗号化専用のヘッダーを指定する必要はありません。例については、[AWS SDK の使用 (低レベル API)](mpu-upload-object.md#mpu-upload-low-level) を参照してください。

次の例では、`TransferManager` を使用してオブジェクトを作成し、SSE−C 関連の情報を提供する方法を示します。この例では、次のような処理を実行します。
+ `TransferManager.upload()` メソッドを使用してオブジェクトを作成します。`PutObjectRequest` インスタンスでは、リクエストで暗号キーの情報を指定します。Amazon S3 は、お客様が用意したキーを使用してオブジェクトを暗号化します。
+ `TransferManager.copy()` メソッドを呼び出してオブジェクトのコピーを作成します。この例では、新しい `SSECustomerKey` を使用してオブジェクトのコピーを暗号化するように Amazon S3 に指示します。ソースオブジェクトは SSE−C で暗号化されているため、`CopyObjectRequest` はソースオブジェクトの暗号化キーを提供し、Amazon S3 で復号してからコピーできるようにします。

**Example**  

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.CopyObjectRequest;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.SSECustomerKey;
import com.amazonaws.services.s3.transfer.Copy;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
import com.amazonaws.services.s3.transfer.Upload;

import javax.crypto.KeyGenerator;
import java.io.File;
import java.security.SecureRandom;

public class ServerSideEncryptionCopyObjectUsingHLwithSSEC {

    public static void main(String[] args) throws Exception {
        Regions clientRegion = Regions.DEFAULT_REGION;
        String bucketName = "*** Bucket name ***";
        String fileToUpload = "*** File path ***";
        String keyName = "*** New object key name ***";
        String targetKeyName = "*** Key name for object copy ***";

        try {
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withRegion(clientRegion)
                    .withCredentials(new ProfileCredentialsProvider())
                    .build();
            TransferManager tm = TransferManagerBuilder.standard()
                    .withS3Client(s3Client)
                    .build();

            // Create an object from a file.
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, keyName, new File(fileToUpload));

            // Create an encryption key.
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(256, new SecureRandom());
            SSECustomerKey sseCustomerEncryptionKey = new SSECustomerKey(keyGenerator.generateKey());

            // Upload the object. TransferManager uploads asynchronously, so this call
            // returns immediately.
            putObjectRequest.setSSECustomerKey(sseCustomerEncryptionKey);
            Upload upload = tm.upload(putObjectRequest);

            // Optionally, wait for the upload to finish before continuing.
            upload.waitForCompletion();
            System.out.println("Object created.");

            // Copy the object and store the copy using SSE-C with a new key.
            CopyObjectRequest copyObjectRequest = new CopyObjectRequest(bucketName, keyName, bucketName, targetKeyName);
            SSECustomerKey sseTargetObjectEncryptionKey = new SSECustomerKey(keyGenerator.generateKey());
            copyObjectRequest.setSourceSSECustomerKey(sseCustomerEncryptionKey);
            copyObjectRequest.setDestinationSSECustomerKey(sseTargetObjectEncryptionKey);

            // Copy the object. TransferManager copies asynchronously, so this call returns
            // immediately.
            Copy copy = tm.copy(copyObjectRequest);

            // Optionally, wait for the upload to finish before continuing.
            copy.waitForCompletion();
            System.out.println("Copy complete.");
        } catch (AmazonServiceException e) {
            // The call was transmitted successfully, but Amazon S3 couldn't process
            // it, so it returned an error response.
            e.printStackTrace();
        } catch (SdkClientException e) {
            // Amazon S3 couldn't be contacted for a response, or the client
            // couldn't parse the response from Amazon S3.
            e.printStackTrace();
        }
    }
}
```

------
#### [ .NET ]

大きなオブジェクトをアップロードするために、マルチパートアップロード API を使用できます (「[Amazon S3 でのマルチパートアップロードを使用したオブジェクトのアップロードとコピー](mpuoverview.md)」を参照)。AWSSDK for .NET には、大きなオブジェクトをアップロードするため、高レベルおよび低レベルの両方の API が用意されています。これらの API は、リクエストでの暗号化関連のヘッダーをサポートします。
+ 高レベルの `Transfer-Utility `API を使用するときには、次に示すように `TransferUtilityUploadRequest` で暗号化固有のヘッダーを提供します。コード例については、[マルチパートアップロードを使用したオブジェクトのアップロード](mpu-upload-object.md) を参照してください。

  ```
  TransferUtilityUploadRequest request = new TransferUtilityUploadRequest()
  {
      FilePath = filePath,
      BucketName = existingBucketName,
      Key = keyName,
      // Provide encryption information.
      ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
      ServerSideEncryptionCustomerProvidedKey = base64Key,
  };
  ```
+ 低レベル API を使用する場合は、マルチパートアップロードの開始リクエストで暗号化関連情報を提供し、以降のパートのアップロードリクエストでは同じ暗号化情報を提供します。マルチパートアップロードの完了リクエストでは、暗号化固有のヘッダーを提供する必要はありません。例については、[AWS SDK の使用 (低レベル API)](mpu-upload-object.md#mpu-upload-low-level) を参照してください。

  既存の大きなオブジェクトをコピーする低レベルのマルチパートアップロードの例を次に示します。この例では、コピーされるオブジェクトは SSE−C を使用して Amazon S3 に保存されており、ターゲットオブジェクトも SSE−C を使用して保存します。例えば、以下を実行します。
  + 暗号化キーと関連情報を提供することによって、マルチパートアップロードのリクエストを開始します。
  + `CopyPartRequest` でソースオブジェクトとターゲットオブジェクトの暗号化キーを提供します。
  + オブジェクトメタデータを取得することによって、コピーされるソースオブジェクトのサイズを取得します。
  + 5 MB のパート単位でオブジェクトをアップロードします。  
**Example**  

  ```
  using Amazon;
  using Amazon.S3;
  using Amazon.S3.Model;
  using System;
  using System.Collections.Generic;
  using System.IO;
  using System.Security.Cryptography;
  using System.Threading.Tasks;
  
  namespace Amazon.DocSamples.S3
  {
      class SSECLowLevelMPUcopyObjectTest
      {
          private const string existingBucketName = "*** bucket name ***";
          private const string sourceKeyName      = "*** source object key name ***"; 
          private const string targetKeyName      = "*** key name for the target object ***";
          private const string filePath           = @"*** file path ***";
          // Specify your bucket region (an example region is shown).
          private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
          private static IAmazonS3 s3Client;
          static void Main()
          {
              s3Client = new AmazonS3Client(bucketRegion);
              CopyObjClientEncryptionKeyAsync().Wait();
          }
  
          private static async Task CopyObjClientEncryptionKeyAsync()
          {
              Aes aesEncryption = Aes.Create();
              aesEncryption.KeySize = 256;
              aesEncryption.GenerateKey();
              string base64Key = Convert.ToBase64String(aesEncryption.Key);
  
              await CreateSampleObjUsingClientEncryptionKeyAsync(base64Key, s3Client);
  
              await CopyObjectAsync(s3Client, base64Key);
          }
          private static async Task CopyObjectAsync(IAmazonS3 s3Client, string base64Key)
          {
              List<CopyPartResponse> uploadResponses = new List<CopyPartResponse>();
  
              // 1. Initialize.
              InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest
              {
                  BucketName = existingBucketName,
                  Key = targetKeyName,
                  ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                  ServerSideEncryptionCustomerProvidedKey = base64Key,
              };
  
              InitiateMultipartUploadResponse initResponse =
                  await s3Client.InitiateMultipartUploadAsync(initiateRequest);
  
              // 2. Upload Parts.
              long partSize = 5 * (long)Math.Pow(2, 20); // 5 MB
              long firstByte = 0;
              long lastByte = partSize;
  
              try
              {
                  // First find source object size. Because object is stored encrypted with
                  // customer provided key you need to provide encryption information in your request.
                  GetObjectMetadataRequest getObjectMetadataRequest = new GetObjectMetadataRequest()
                  {
                      BucketName = existingBucketName,
                      Key = sourceKeyName,
                      ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                      ServerSideEncryptionCustomerProvidedKey = base64Key // " * **source object encryption key ***"
                  };
  
                  GetObjectMetadataResponse getObjectMetadataResponse = await s3Client.GetObjectMetadataAsync(getObjectMetadataRequest);
  
                  long filePosition = 0;
                  for (int i = 1; filePosition < getObjectMetadataResponse.ContentLength; i++)
                  {
                      CopyPartRequest copyPartRequest = new CopyPartRequest
                      {
                          UploadId = initResponse.UploadId,
                          // Source.
                          SourceBucket = existingBucketName,
                          SourceKey = sourceKeyName,
                          // Source object is stored using SSE-C. Provide encryption information.
                          CopySourceServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                          CopySourceServerSideEncryptionCustomerProvidedKey = base64Key, //"***source object encryption key ***",
                          FirstByte = firstByte,
                          // If the last part is smaller then our normal part size then use the remaining size.
                          LastByte = lastByte > getObjectMetadataResponse.ContentLength ?
                              getObjectMetadataResponse.ContentLength - 1 : lastByte,
  
                          // Target.
                          DestinationBucket = existingBucketName,
                          DestinationKey = targetKeyName,
                          PartNumber = i,
                          // Encryption information for the target object.
                          ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                          ServerSideEncryptionCustomerProvidedKey = base64Key
                      };
                      uploadResponses.Add(await s3Client.CopyPartAsync(copyPartRequest));
                      filePosition += partSize;
                      firstByte += partSize;
                      lastByte += partSize;
                  }
  
                  // Step 3: complete.
                  CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest
                  {
                      BucketName = existingBucketName,
                      Key = targetKeyName,
                      UploadId = initResponse.UploadId,
                  };
                  completeRequest.AddPartETags(uploadResponses);
  
                  CompleteMultipartUploadResponse completeUploadResponse =
                      await s3Client.CompleteMultipartUploadAsync(completeRequest);
              }
              catch (Exception exception)
              {
                  Console.WriteLine("Exception occurred: {0}", exception.Message);
                  AbortMultipartUploadRequest abortMPURequest = new AbortMultipartUploadRequest
                  {
                      BucketName = existingBucketName,
                      Key = targetKeyName,
                      UploadId = initResponse.UploadId
                  };
                  s3Client.AbortMultipartUpload(abortMPURequest);
              }
          }
          private static async Task CreateSampleObjUsingClientEncryptionKeyAsync(string base64Key, IAmazonS3 s3Client)
          {
              // List to store upload part responses.
              List<UploadPartResponse> uploadResponses = new List<UploadPartResponse>();
  
              // 1. Initialize.
              InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest
              {
                  BucketName = existingBucketName,
                  Key = sourceKeyName,
                  ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                  ServerSideEncryptionCustomerProvidedKey = base64Key
              };
  
              InitiateMultipartUploadResponse initResponse =
                 await s3Client.InitiateMultipartUploadAsync(initiateRequest);
  
              // 2. Upload Parts.
              long contentLength = new FileInfo(filePath).Length;
              long partSize = 5 * (long)Math.Pow(2, 20); // 5 MB
  
              try
              {
                  long filePosition = 0;
                  for (int i = 1; filePosition < contentLength; i++)
                  {
                      UploadPartRequest uploadRequest = new UploadPartRequest
                      {
                          BucketName = existingBucketName,
                          Key = sourceKeyName,
                          UploadId = initResponse.UploadId,
                          PartNumber = i,
                          PartSize = partSize,
                          FilePosition = filePosition,
                          FilePath = filePath,
                          ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                          ServerSideEncryptionCustomerProvidedKey = base64Key
                      };
  
                      // Upload part and add response to our list.
                      uploadResponses.Add(await s3Client.UploadPartAsync(uploadRequest));
  
                      filePosition += partSize;
                  }
  
                  // Step 3: complete.
                  CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest
                  {
                      BucketName = existingBucketName,
                      Key = sourceKeyName,
                      UploadId = initResponse.UploadId,
                      //PartETags = new List<PartETag>(uploadResponses)
  
                  };
                  completeRequest.AddPartETags(uploadResponses);
  
                  CompleteMultipartUploadResponse completeUploadResponse =
                      await s3Client.CompleteMultipartUploadAsync(completeRequest);
  
              }
              catch (Exception exception)
              {
                  Console.WriteLine("Exception occurred: {0}", exception.Message);
                  AbortMultipartUploadRequest abortMPURequest = new AbortMultipartUploadRequest
                  {
                      BucketName = existingBucketName,
                      Key = sourceKeyName,
                      UploadId = initResponse.UploadId
                  };
                  await s3Client.AbortMultipartUploadAsync(abortMPURequest);
              }
          }
      }
  }
  ```

------

# 汎用バケットの SSE-C のブロックまたはブロック解除
<a name="blocking-unblocking-s3-c-encryption-gpb"></a>

Amazon S3 の最新のユースケースでは、Amazon S3 マネージドキーによるサーバー側の暗号化 (SSE-S3) または AWS KMS キーによるサーバー側の暗号化 (SSE-KMS) の柔軟性がないため、お客様が用意したキーによるサーバー側の暗号化 (SSE-C) は使用されなくなりました。SSE-C では、SSE-C 暗号化データとやり取りするたびに暗号化キーを提供する必要があるため、S3 バケットからデータを読み取ってデータを操作しようとする他のユーザー、ロール、または AWS のサービスと SSE-C キーを共有することは実用的ではありません。

汎用バケットで使用できるサーバー側の暗号化タイプを制限するには、バケットのデフォルトの暗号化設定を更新して SSE-C 書き込みリクエストをブロックすることを選択できます。このバケットレベルの設定は、SSE-C を指定するオブジェクトをアップロードするリクエストをブロックします。バケットに対して SSE-C がブロックされている場合、SSE-C 暗号化を指定する `PutObject`、`CopyObject`、`PostObject`、またはマルチパートアップロードまたはレプリケーションリクエストは、HTTP 403 `AccessDenied` エラーで拒否されます。

この設定は `PutBucketEncryption` API のパラメータであり、`s3:PutEncryptionConfiguration` アクセス許可がある場合は S3 コンソール、AWS CLI、および AWS SDK を使用して更新することもできます。

有効な値は、汎用バケットの SSE-C 暗号化をブロックする `SSE-C` と、バケットへの書き込みに SSE-C を使用できるようにする `NONE` です。

**重要**  
2026 年 4 月以降、AWS はすべての新しいバケットについて、お客様が用意したキー (SSE-C) によるサーバー側の暗号化を無効にします。さらに、SSE-C 暗号化は、SSE-C 暗号化データを持たない AWS アカウントのすべての既存のバケットに対して無効になります。これらの変更により、SSE-C 暗号化を必要とする少数のアプリケーションは、バケットの作成後に [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) API を介して SSE-C の使用を意図的に有効にする必要があります。このような場合、自動化スクリプト、CloudFormation テンプレート、またはその他のインフラストラクチャ設定ツールを更新して、これらの設定を構成する必要がある場合があります。詳細については、[AWS ストレージブログ記事](https://aws.amazon.com/blogs/storage/advanced-notice-amazon-s3-to-disable-the-use-of-sse-c-encryption-by-default-for-all-new-buckets-and-select-existing-buckets-in-april-2026/)を参照してください。

## アクセス許可
<a name="bucket-encryption-permissions"></a>

`PutBucketEncryption` API または S3 コンソール、AWS SDK、または AWS CLI を使用して、汎用バケットの暗号化タイプをブロックまたはブロック解除します。次のアクセス許可が必要です。
+ `s3:PutEncryptionConfiguration`

`GetBucketEncryption` API または S3 コンソール、AWS SDK、または AWS CLI を使用して、汎用バケットのブロックされた暗号化タイプを表示します。次のアクセス許可が必要です。
+ `s3:GetEncryptionConfiguration`

## SSE-C 暗号化をブロックする前の考慮事項
<a name="considerations-before-blocking-sse-c"></a>

バケットの SSE-C をブロックすると、次の暗号化動作が適用されます。
+ SSE-C 暗号化をブロックする前にバケットに存在していたオブジェクトの暗号化は、変更されません。
+ SSE-C 暗号化をブロックした後、リクエストに必要な SSE-C ヘッダーを提供する限り、SSE-C で暗号化された既存のオブジェクトに対して GetObject および HeadObject リクエストを引き続き実行できます。
+ バケットに対して SSE-C がブロックされている場合、SSE-C 暗号化を指定する `PutObject`、`CopyObject`、`PostObject`、またはマルチパートアップロードリクエストは、HTTP 403 `AccessDenied` エラーで拒否されます。
+ レプリケーションの送信先バケットで SSE-C がブロックされ、レプリケートされるソースオブジェクトが SSE-C で暗号化されている場合、レプリケーションは HTTP 403 `AccessDenied` エラーで失敗します。

この暗号化タイプをブロックする前に、いずれかのバケットで SSE-C 暗号化を使用しているかどうかを確認する場合は、[AWS CloudTrail](https://aws.amazon.com/cloudtrail/) などのツールを使用してデータへのアクセスをモニタリングできます。この[ブログ記事](https://aws.amazon.com/blogs/storage/auditing-amazon-s3-server-side-encryption-methods-for-object-uploads/)では、オブジェクトのアップロードの暗号化方法をリアルタイムで監査する方法を示します。この [re:Post 記事](https://repost.aws/articles/ARhGC12rOiTBCKHcAe9GZXCA/how-to-detect-existing-use-of-sse-c-in-your-amazon-s3-buckets)を参照して、S3 インベントリレポートのクエリを実行して、SSE-C で暗号化されたオブジェクトがあるかどうかを確認することもできます。

### Steps
<a name="block-sse-c-gpb-steps"></a>

Amazon S3 コンソール、AWS Command Line Interface (AWS CLI)、Amazon S3 REST API、および AWS SDK を使用して、汎用バケットのお客様が用意したキーによるサーバー側の暗号化 (SSE-C) をブロックまたはブロック解除できます。

### S3 コンソールの使用
<a name="block-sse-c-gpb-console"></a>

Amazon S3 コンソールを使用してバケットの SSE-C 暗号化をブロックまたはブロック解除するには。

1. AWS マネジメントコンソールにサインインして Amazon S3 コンソール (https://console.aws.amazon.com/s3/) を開きます。

1. 左のナビゲーションペインで、**[汎用バケット]** を選択します。

1. SSE-C 暗号化をブロックするバケットを選択します。

1. バケットの **[プロパティ]** タブを選択します。

1. バケットの **[デフォルトの暗号化]** プロパティパネルに移動し、**[編集]** を選択します。

1. **[ブロックされた暗号化タイプ]** セクションで、**[お客様が用意したキーによるサーバー側の暗号化 (SSE-C)]** の横にあるチェックボックスをオンにして SSE-C 暗号化をブロックするか、このチェックボックスをオフにして SSE-C を許可します。

1. **[Save Changes]** (変更を保存) をクリックします。

### の使用AWS CLI
<a name="block-sse-c-gpb-cli"></a>

AWS CLI をインストールする方法については、「*AWS Command Line Interface ユーザーガイド*」の「[AWS CLI のインストール](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)」を参照してください。

次の CLI の例は、AWS CLI を使用して汎用バケットの SSE-C 暗号化をブロックまたはブロック解除する方法を示しています。このコマンドを使用する際は、*ユーザー入力用プレースホルダー*を独自の情報に置き換えます。

**汎用バケットの SSE-C 暗号化をブロックするリクエスト:**

```
aws s3api put-bucket-encryption \
  --bucket amzn-s3-demo-bucket \
  --server-side-encryption-configuration '{
    "Rules": [{
      "BlockEncryptionTypes": {
        "EncryptionType": "SSE-C"
      }
    }]
  }'
```

**汎用バケットで SSE-C 暗号化の使用を有効にするリクエスト:**

```
aws s3api put-bucket-encryption \
  --bucket amzn-s3-demo-bucket \
  --server-side-encryption-configuration '{
    "Rules": [{
      "BlockEncryptionTypes": {
        "EncryptionType": "NONE"
      }
    }]
  }'
```

## AWS SDK の使用
<a name="block-sse-c-gpb-sdks"></a>

------
#### [ SDK for Java 2.x ]

次の例は、AWS SDK を使用して汎用バケットへの SSE-C 暗号化書き込みをブロックまたはブロック解除する方法を示しています。

**例 - PutBucketEncryption リクエストでデフォルトの暗号化設定を SSE-S3 に設定し、SSE-C をブロックする**

```
S3Client s3Client = ...;
ServerSideEncryptionByDefault defaultSse = ServerSideEncryptionByDefault
        .builder()
        .sseAlgorithm(ServerSideEncryption.AES256)
        .build();
BlockedEncryptionTypes blockedEncryptionTypes = BlockedEncryptionTypes
        .builder()
        .encryptionType(EncryptionType.SSE_C)
        .build();
ServerSideEncryptionRule rule = ServerSideEncryptionRule.builder()
        .applyServerSideEncryptionByDefault(defaultSse)
        .blockedEncryptionTypes(blockedEncryptionTypes)
        .build();
s3Client.putBucketEncryption(be -> be
        .bucket(bucketName)
        .serverSideEncryptionConfiguration(c -> c.rules(rule)));
```

**例 - PutBucketEncryption リクエストでデフォルトの暗号化設定を SSE-S3 に設定し、SSE-C のブロックを解除する**

```
S3Client s3Client = ...;
ServerSideEncryptionByDefault defaultSse = ServerSideEncryptionByDefault
        .builder()
        .sseAlgorithm(ServerSideEncryption.AES256)
        .build();
BlockedEncryptionTypes blockedEncryptionTypes = BlockedEncryptionTypes
        .builder()
        .encryptionType(EncryptionType.NONE)
        .build();
ServerSideEncryptionRule rule = ServerSideEncryptionRule.builder()
        .applyServerSideEncryptionByDefault(defaultSse)
        .blockedEncryptionTypes(blockedEncryptionTypes)
        .build();
s3Client.putBucketEncryption(be -> be
        .bucket(bucketName)
        .serverSideEncryptionConfiguration(c -> c.rules(rule)));
```

------
#### [ SDK for Python Boto3 ]

**例 - PutBucketEncryption リクエストでデフォルトの暗号化設定を SSE-S3 に設定し、SSE-C をブロックする**

```
s3 = boto3.client("s3")
s3.put_bucket_encryption(
    Bucket="amzn-s3-demo-bucket",
    ServerSideEncryptionConfiguration={
        "Rules":[{
            "ApplyServerSideEncryptionByDefault": {
                "SSEAlgorithm": "AES256"
            },
            "BlockedEncryptionTypes": {
                "EncryptionType": ["SSE-C"]
            }
        }]
    }
)
```

**例 - PutBucketEncryption リクエストでデフォルトの暗号化設定を SSE-S3 に設定し、SSE-C のブロックを解除する**

```
s3 = boto3.client("s3")
s3.put_bucket_encryption(
    Bucket="amzn-s3-demo-bucket",
    ServerSideEncryptionConfiguration={
        "Rules":[{
            "ApplyServerSideEncryptionByDefault": {
                "SSEAlgorithm": "AES256"
            },
            "BlockedEncryptionTypes": {
                "EncryptionType": ["NONE"]
            }
        }]
    }
)
```

------

## REST API の使用
<a name="bucket-tag-add-api"></a>

汎用バケットの SSE-C 暗号化のブロックまたはブロック解除に関する Amazon S3 REST API サポートの詳細については、「*Amazon Simple Storage Service API リファレンス*」の次のセクションを参照してください。
+ [PutBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) および [GetBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html) API オペレーションの [ServerSideEncryptionRule](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ServerSideEncryptionRule.html) データ型で使用される [BlockedEncryptionTypes](https://docs.aws.amazon.com/AmazonS3/latest/API/API_BlockedEncryptionTypes.html) データ型。

# 新しいバケットの SSE-C 設定に関するよくある質問
<a name="default-s3-c-encryption-setting-faq"></a>

**重要**  
2026 年 4 月以降、AWS はすべての新しいバケットについて、お客様が用意したキー (SSE-C) によるサーバー側の暗号化を無効にします。さらに、SSE-C 暗号化は、SSE-C 暗号化データを持たない AWS アカウントのすべての既存のバケットに対して無効になります。これらの変更により、SSE-C 暗号化を必要とする少数のアプリケーションは、バケットの作成後に [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) API を介して SSE-C の使用を意図的に有効にする必要があります。このような場合、自動化スクリプト、CloudFormation テンプレート、またはその他のインフラストラクチャ設定ツールを更新して、これらの設定を構成する必要がある場合があります。詳細については、[AWS ストレージブログ記事](https://aws.amazon.com/blogs/storage/advanced-notice-amazon-s3-to-disable-the-use-of-sse-c-encryption-by-default-for-all-new-buckets-and-select-existing-buckets-in-april-2026/)を参照してください。

以下のセクションでは、この更新に関する質問に答えます。

**1. 2026 年 4 月には、新しく作成されたすべてのバケットに新しい SSE-C 設定が適用されますか?**

はい。2026 年 4 月中に、新しいデフォルト設定がすべての AWS リージョンに徐々に展開されます。

**2. このロールアウトがすべての AWS リージョンをカバーするまでにはどれくらいの時間がかかりますか?**

このアップデートの導入には数週間かかります。このアップデートの導入開始時には、「最新情報」の記事を公開します。

**3. 更新が完了したかどうかはどうすればわかりますか?**

新しいバケットを作成し、[GetBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html) API オペレーションを呼び出して SSE-C 暗号化が無効になっているかどうかを判断することで、ユーザーの AWS リージョンで変更が完了したかどうかを簡単に判断できます。更新が完了すると、すべての新しい汎用バケットでは SSE-C 暗号化がデフォルトで自動的に無効になります。これらの設定は、S3 バケットの作成後に [PutBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) API オペレーションを呼び出して調整できます。

**4. Amazon S3 は既存のバケット設定を更新しますか?**

AWS アカウントに SSE-C 暗号化オブジェクトがない場合、AWS は既存のすべてのバケットで SSE-C 暗号化を無効にします。AWS アカウントのバケットに SSE-C で暗号化されたオブジェクトがある場合、AWS はそのアカウントのバケットのバケット設定を変更しません。AWS リージョン `CreateBucket` の変更が完了すると、新しいデフォルト設定がすべての新しい汎用バケットに適用されます。

 **5. 更新が完了する前にバケットの SSE-C 暗号化を無効にすることはできますか?**

はい。[PutBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) API オペレーションを呼び出して新しい `BlockedEncryptionTypes` ヘッダーを指定することで、任意のバケットの SSE-C 暗号化を無効にすることができます。

**6. SSE-C を使用して新しいバケット内のデータを暗号化できますか?**

はい。Amazon S3 の最新のユースケースのほとんどでは、Amazon S3 マネージドキーによるサーバー側の暗号化 (SSE-S3) や AWS KMS キーによるサーバー側の暗号化 (SSE-KMS) の柔軟性が欠けているため、SSE-C は使用されなくなりました。新しいバケットで SSE-C 暗号化を使用する必要がある場合は、新しいバケットを作成してから、別の `PutBucketEncryption` リクエストで SSE-C 暗号化の使用を有効にすることができます。

 **例**

```
aws s3api create-bucket \  
bucket amzn-s3-demo-bucket \ 
region us-east-1 \ 
  
aws s3api put-bucket-encryption \  
-- bucket amzn-s3-demo-bucket \
-- server-side-encryption-configuration \
'{ \Rules\: [{   
   {   
   \ApplyServerSideEncryptionByDefault\: {   
     \SSEAlgorithm\: \AES256\,  
    },   
   \BlockedEncryptionTypes\: [  
     \EncryptionType\:\NONE\]   
   }   
   }]   
}'
```

**注記**  
`PutBucketEncryption` API を呼び出すには、`s3:PutEncryptionConfiguration` アクセス許可が必要です。

**7. SSE-C をブロックすると、バケットへのリクエストにどのような影響がありますか?**

バケットに対して SSE-C がブロックされている場合、SSE-C 暗号化を指定する `PutObject`、`CopyObject`、`PostObject`、またはマルチパートアップロードまたはレプリケーションリクエストは、HTTP 403 `AccessDenied` エラーで拒否されます。