

# Amazon S3 でのオブジェクトの整合性のチェック
<a name="checking-object-integrity"></a>

Amazon S3 は、オブジェクトのストレージライフサイクル全体でさまざまなデータ保護機能を提供します。Amazon S3 では、チェックサム値を使用して、アップロードまたはダウンロードするデータの整合性を検証できます。さらに、S3 に保存するオブジェクトについて、別のチェックサム値を計算するようにリクエストすることもできます。

データをアップロード、コピー、または管理する場合は、サポートされているいくつかのチェックサムアルゴリズムから選択できます。
+ CRC-64/NVME (`CRC64NVME`)
**注記**  
`CRC64NVME` チェックサムアルゴリズムは、チェックサム計算に使用されるデフォルトのチェックサムアルゴリズムです。
+ CRC-32 (`CRC32`)
+ CRC-32C (`CRC32C`)
+ SHA-1 (`SHA1`)
+ SHA-256 (`SHA256`)
+ MD5 (`MD5`)
**注記**  
マルチパートアップロードの場合、[チェックサムを計算] オペレーションは `MD5` を使用してフルオブジェクトのチェックサム値を提供します。これはアップロード中には使用できません。単一パートアップロードの場合、`content-MD5 header` はオブジェクトの S3 ETag を使用してのみ利用でき、SSE-S3 暗号化を使用する必要があります。

オブジェクトを S3 にアップロードする際に、チェックサムのアルゴリズムの使用法を指定できます。アップロードでは、すべての AWS 所有クライアントでオブジェクトのチェックサムが計算され、アップロードリクエストとともに送信されます。次に、S3 はサーバー側のオブジェクトのチェックサム値を個別に計算し、指定された値で検証してから、オブジェクトとチェックサム値を保存します。単一パートアップロードまたはマルチパートアップロードを実行するときに (マルチパートアップロードにはフルオブジェクトのチェックサムタイプを使用)、これらのチェックサムアルゴリズムに事前計算された値を指定することもできます。複数のオブジェクトで事前計算された値を使用するには、AWS CLI または AWS SDK を使用します。

あるいは、データを復元またはダウンロードすることなく S3 でデータセットを検証する場合は、S3 バッチオペレーションで **[チェックサムを計算]** オペレーションを使用できます。**[チェックサムを計算]** オペレーションを使用すると、1 つのジョブリクエストで数十億のオブジェクトを効率的に検証できます。**[チェックサムを計算]** オペレーションが実行されると、S3 は保管中のオブジェクトのリストのチェックサム値を計算します。ジョブリクエストの最後に、自動的に生成された整合性レポート (完了レポートとも呼ばれます) を受け取ります。これを使用して、データセットがそのまま維持されていることを確認できます。

**Topics**
+ [Amazon S3 でデータアップロードのオブジェクトの整合性をチェックする](checking-object-integrity-upload.md)
+ [Amazon S3 で保管中のデータのオブジェクトの整合性を確認する](checking-object-integrity-at-rest.md)

# Amazon S3 でデータアップロードのオブジェクトの整合性をチェックする
<a name="checking-object-integrity-upload"></a>

Amazon S3 は、チェックサム値を使用して、アップロードおよびダウンロードオペレーション中のデータの整合性を検証します。データをアップロードすると、AWS SDK と AWS マネジメントコンソールは選択したチェックサムアルゴリズムを使用して、データ転送前にチェックサム値を計算します。次に、S3 はデータのチェックサムを個別に計算し、指定されたチェックサム値と照合して検証します。オブジェクトは、転送中にデータの整合性が維持されたことを確認した後にのみ受け入れられます。S3 は、チェックサム値をオブジェクトメタデータとして保存し、オブジェクト自体も保存します。

オブジェクトのデータ整合性を検証する場合は、ダウンロード中にチェックサム値をリクエストできます。この検証は、単一パートアップロードとマルチパートアップロードの両方に対して、暗号化モード、オブジェクトサイズ、ストレージクラス間で一貫して機能します。アップロードのチェックサムアルゴリズムを変更するには、個々のオブジェクトをコピーするか、複数のオブジェクトにバッチコピーを使用します。

単一パートアップロードの場合、チェックサム値をヘッダーとして指定できます。事前に計算された値を指定するか、アップロード中に AWS SDK に計算させることができます。S3 で計算したチェックサム値と指定した値が一致すると、リクエストが受け入れられます。値が一致しない場合、リクエストは拒否されます。

マルチパートアップロードの場合、AWS SDK はチャンクアップロードの追跡チェックサムを自動的に作成できます。追跡チェックサムを使用すると、Amazon S3 は指定したアルゴリズムを使用して各パートのチェックサム値を生成し、チャンクアップロードリクエストの最後にチェックサム値を追加します。S3 は検証とアップロードを 1 回のパスで実行し、効率を向上させます。詳細については、「[追跡チェックサムの使用](#trailing-checksums)」を参照してください。

## サポートされているチェックサムアルゴリズムの使用
<a name="using-additional-checksums"></a>

Amazon S3 では、チェックサムアルゴリズムを選択して、アップロード中にチェックサム値を計算できます。その後、指定されたチェックサムアルゴリズムがオブジェクトとともに保存され、ダウンロード中にデータの整合性を検証するために使用できます。チェックサム値を計算するには、セキュアハッシュアルゴリズム (SHA) または巡回冗長検査 (CRC) チェックアルゴリズムのいずれかを選択できます。
+ CRC-64/NVME (`CRC64NVME`)
+ CRC-32 (`CRC32`)
+ CRC-32C (`CRC32C`)
+ SHA-1 (`SHA1`)
+ SHA-256 (`SHA256`)
+ MD5 (`MD5`)
**注記**  
`content-MD5` ヘッダーは、SSE-S3 暗号化を使用する単一パートアップロード (`PUT` オペレーション) でアップロードされたオブジェクトに対して、S3 ETag を使用する場合にのみ利用可能です。

さらに、Content-MD5 ヘッダーを使用して、各リクエストにチェックサムを提供できます。

[オブジェクトをアップロード](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html)するときに、使用するアルゴリズムを指定します。
+ **AWS マネジメントコンソール を使用するときには**、使用するチェックサムアルゴリズムを選択します。オプションでオブジェクトのチェックサム値を指定できます。Amazon S3 は、オブジェクトを受信すると、指定したアルゴリズムを使用してチェックサムを計算します。2 つの値が一致しない場合、Amazon S3 はエラーを生成します。
+ **SDK を使用するときには**、以下について注意してください。
  + `ChecksumAlgorithm` パラメータを Amazon S3 で使用するアルゴリズムに設定します。事前に計算されたチェックサムが既にある場合は、チェックサム値を AWS SDK に渡すと、SDK はリクエストにその値を含めます。チェックサム値を渡さないか、チェックサムアルゴリズムを指定しない場合、SDK はチェックサム値を自動的に計算し、リクエストに含めて整合性の保護を提供します。個々のチェックサム値がチェックサムアルゴリズムの設定値と一致しない場合、Amazon S3 は `BadDigest` エラーでリクエストに失敗します。
  + アップグレードされた AWS SDK を使用している場合、SDK がチェックサムアルゴリズムを選択します。ただし、このチェックサムアルゴリズムは上書きできます。
  + チェックサムアルゴリズムを指定せず、SDK もチェックサムを計算しない場合、S3 は自動的に CRC-64/NVME (`CRC64NVME`) チェックサムアルゴリズムを選択します。
+ **REST API を使用しているときには**、`x-amz-sdk-checksum-algorithm` パラメータを使用しないでください。代わりに、アルゴリズム固有のヘッダーのいずれかを使用します (例: `x-amz-checksum-crc32`)。

Amazon S3 に既にアップロードされているオブジェクトにこれらのチェックサム値のいずれかを適用するには、オブジェクトをコピーして、既存のチェックサムアルゴリズムを使用するか、新しいチェックサムアルゴリズムを使用するかを指定します。アルゴリズムを指定しない場合、S3 は既存のアルゴリズムを使用します。ソースオブジェクトに指定されたチェックサムアルゴリズムまたはチェックサム値がない場合、Amazon S3 は CRC-64/NVME アルゴリズムを使用して送信先オブジェクトのチェックサム値を計算します。[S3 バッチオペレーション](https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops.html)を使用してオブジェクトをコピーするときに、チェックサムアルゴリズムを指定することもできます。

**重要**  
複合 (またはパートレベル) チェックサムの **[チェックサム]** でマルチパートアップロードを使用する場合、マルチパートアップロードのパート番号は、連続しており 1 から始まる必要があります。連続しないパート番号でマルチパートアップロードリクエストを完了しようとすると、Amazon S3 は `HTTP 500 Internal Server` エラーを生成します。

## フルオブジェクトおよび複合チェックサムタイプ
<a name="ChecksumTypes-Uploads"></a>

Amazon S3 では、次の 2 つのタイプのチェックサムがサポートされています。
+ **フルオブジェクトチェックサム:** フルオブジェクトチェックサムは、マルチパートアップロードのすべてのコンテンツに基づいて計算され、最初のパートの最初のバイトから最後のパートの最後のバイトまでのすべてのデータをカバーします。AWS マネジメントコンソールを使用して 16 MB 未満のオブジェクトをアップロードする場合、フルオブジェクトのチェックサムタイプのみがサポートされることに注意してください。
**注記**  
すべての PUT リクエストには、フルオブジェクトのチェックサムタイプが必要です。PUT リクエストを介してオブジェクトをアップロードする場合は、フルオブジェクトのチェックサムタイプを指定する必要があります。
+ **複合チェックサム:** 複合チェックサムは、マルチパートアップロードの各パートの個々のチェックサムに基づいて計算されます。このアプローチでは、すべてのデータコンテンツに基づいてチェックサムを計算する代わりに、パートレベルのチェックサム (最初の部分から最後の部分まで) を集計して、完全なオブジェクトに対する単一の複合チェックサムを生成します。マルチパートアップロードを使用してオブジェクトをアップロードする場合は、複合チェックサムタイプを指定する必要があります。
**注記**  
オブジェクトがマルチパートアップロードとしてアップロードされるとき、オブジェクトのエンティティタグ (ETag) はオブジェクト全体の MD5 ダイジェストではありません。代わりに、Amazon S3 は、アップロードされた個々のパートの MD5 ダイジェストを計算します。MD5 ダイジェストは、最終的なオブジェクトの ETag を決定するために使用されます。Amazon S3 は MD5 ダイジェストのバイトを連結し、これらの連結値の MD5 ダイジェストを計算します。ETag 作成最終ステップの間に、Amazon S3 はパートの総数を含むダッシュを末尾に追加します。

Amazon S3 は、次のフルオブジェクトおよび複合チェックサムアルゴリズムタイプをサポートしています。
+ CRC-64/NVME (`CRC64NVME`): フルオブジェクトのチェックサムタイプのみをサポートします。
+ CRC-32 (`CRC32`): フルオブジェクトおよび複合チェックサムタイプの両方をサポートします。
+ CRC-32C (`CRC32C`): フルオブジェクトおよび複合チェックサムタイプの両方をサポートします。
+ SHA-1 (`SHA1`): フルオブジェクトおよび複合チェックサムタイプの両方をサポートします。
+ SHA-256 (`SHA256`): フルオブジェクトおよび複合チェックサムタイプの両方をサポートします。
+ MD5 (`MD5`): フルオブジェクトおよび複合チェックサムタイプの両方をサポートします。

### シングルパートアップロード
<a name="SinglePartUploads-Checksums"></a>

シングルパートでアップロード ([https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html#API_PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html#API_PutObject) を使用) されたオブジェクトのチェックサムは、フルオブジェクトチェックサムとして扱われます。Amazon S3 コンソールでオブジェクトをアップロードするときに、S3 で使用するチェックサムアルゴリズムを選択し、(オプションで) 事前に計算された値を指定することもできます。次に、Amazon S3 は、オブジェクトとそのチェックサム値を保存する前に、事前に計算されたチェックサム値を検証します。オブジェクトのダウンロード中にチェックサム値をリクエストするときに、オブジェクトのデータ整合性を検証できます。

### マルチパートアップロード
<a name="MultipartUploads-Checksums"></a>

[https://docs.aws.amazon.com/AmazonS3/latest/API/API_MultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_MultipartUpload.html) API を使用してオブジェクトを複数のパートに分けてアップロードする場合、Amazon S3 で使用するチェックサムアルゴリズムとチェックサムタイプ (フルオブジェクトまたは複合) を指定できます。

 次の表は、マルチパートアップロードの各チェックサムアルゴリズムでサポートされているチェックサムアルゴリズムタイプを示しています。


| チェックサムアルゴリズム | フルオブジェクト | 複合 | 
| --- | --- | --- | 
| CRC-64/NVME (CRC64NVME) | はい | なし | 
| CRC-32 (CRC32) | 可能 | はい | 
| CRC-32C (CRC32C) | 可能 | はい | 
| SHA-1 (SHA1) | いいえ | あり | 
| SHA-256 (SHA256) | いいえ | あり | 

## マルチパートアップロードへのフルオブジェクトチェックサムの使用
<a name="Full-object-checksums"></a>

マルチパートアップロードを作成または実行するときは、アップロード時の検証にフルオブジェクトチェックサムを使用できます。つまり、[https://docs.aws.amazon.com/AmazonS3/latest/API/API_MultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_MultipartUpload.html) API にチェックサムアルゴリズムを提供できることを意味します。アップロードされたオブジェクトのパート境界を追跡する必要がなくなるため、整合性検証ツールを簡素化できます。オブジェクト全体のチェックサムとオブジェクトサイズを [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) リクエストで指定できます。

マルチパートアップロード中にフルオブジェクトチェックサムを指定すると、AWS SDK はそのチェックサムを Amazon S3 に渡し、S3 はオブジェクトの整合性をサーバー側で検証して、受信した値と比較します。次に、値が一致すると、Amazon S3 はオブジェクトを保存します。2 つの値が一致しない場合、S3 は `BadDigest` エラーでリクエストに失敗します。オブジェクトのチェックサムはオブジェクトメタデータにも保存され、後でオブジェクトのデータ整合性を検証するために使用します。

フルオブジェクトチェックサムには、S3 で CRC-64/NVME (`CRC64NVME`)、CRC-32 (`CRC32`)、または CRC-32C (`CRC32C`) チェックサムアルゴリズムを使用できます。マルチパートアップロードのフルオブジェクトチェックサムは、フルオブジェクトチェックサムに線形化できるため、CRC ベースのチェックサムでのみ使用できます。この線形化により、Amazon S3 はリクエストを並列化してパフォーマンスを向上させることができます。特に、S3 はパートレベルのチェックサムからオブジェクト全体のチェックサムを計算できます。このタイプの検証は、SHA や MD5 などの他のアルゴリズムでは使用できません。S3 にはデフォルトの整合性保護があるため、チェックサムなしでオブジェクトをアップロードすると、S3 は推奨されるフルオブジェクト CRC-64/NVME (`CRC64NVME`) チェックサムアルゴリズムをオブジェクトに自動的にアタッチします。

**注記**  
マルチパートアップロードを開始するには、チェックサムアルゴリズムとフルオブジェクトチェックサムタイプを指定できます。チェックサムアルゴリズムとフルオブジェクトチェックサムタイプを指定した後、マルチパートアップロードのフルオブジェクトチェックサム値を指定できます。

## マルチパートアップロードへのパートレベルのチェックサムの使用
<a name="Part-level-checksums"></a>

オブジェクトが Amazon S3 にアップロードされるときには、単一のオブジェクトとしてアップロードされるか、マルチパートアップロードプロセスを使用してパートに分割してアップロードされます。マルチパートアップロードの **[チェックサム]** タイプを選択できます。マルチパートアップロードのパートレベルのチェックサム (または複合チェックサム) の場合、Amazon S3 は指定されたチェックサムアルゴリズムを使用して個々のパートのチェックサムを計算します。[https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) を使用して、各パートのチェックサム値を指定できます。Amazon S3 コンソールでアップロードしようとしているオブジェクトが CRC-64/NVME (`CRC64NVME`) チェックサムアルゴリズムを使用するように設定されていて、16 MB を超える場合は、自動的にフルオブジェクトチェックサムとして指定されます。

次に、Amazon S3 は保存されたパートレベルのチェックサム値を使用して、各パートが正しくアップロードされたことを確認します。各パートのチェックサム (オブジェクト全体) を指定すると、S3 は各パートの保存されたチェックサム値を使用して、指定されたチェックサム値と比較し、フルオブジェクトチェックサムを内部的に計算します。これにより、S3 はパートのチェックサムを使用してオブジェクト全体のチェックサムを計算でき、コンピューティングコストが最小限に抑えられます。マルチパートアップロードの詳細については、「[Amazon S3 でのマルチパートアップロードを使用したオブジェクトのアップロードとコピー](mpuoverview.md)」と「[マルチパートアップロードへのフルオブジェクトチェックサムの使用](#Full-object-checksums)」を参照してください。

オブジェクトが完全にアップロードされたら、最後に計算されたチェックサムを使用して、オブジェクトのデータ整合性を検証できます。

マルチパートアップロードの一部をアップロードするときは、次の点に注意してください。
+ オブジェクト全体を構成するパートの数など、オブジェクトに関する情報を取得するには、[https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) オペレーションを使用します。追加のチェックサムを使用すると、パートのチェックサム値を含む個々のパートの情報を回復することもできます。
+ 完了したアップロードでは、[https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) または [https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html) オペレーションを使用して、シングルパートのパート番号またはバイト範囲を指定することにより、個々のパートのチェックサムを取得することもできます。マルチパートアップロード処理中の個別のパートのチェックサム値を取得する場合は、[https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) を使用できます。
+ Amazon S3 はマルチパートオブジェクトのチェックサムを計算するので、オブジェクトをコピーした場合、チェックサム値が変更されることがあります。SDK または REST API を使用しており、[https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) を呼び出した場合、Amazon S3 は `CopyObject` API オペレーションのサイズ制限までオブジェクトをコピーします。Amazon S3 は、オブジェクトが単一のリクエストでアップロードされたか、マルチパートアップロードの一部としてアップロードされたかにかかわらず、このコピーを単一のアクションとして実行します。copy コマンドでは、オブジェクトのチェックサムは、完全なオブジェクトの直接チェックサムです。オブジェクトが最初にマルチパートアップロードを使用してアップロードされた場合、データに変更がない場合でも、チェックサム値が変更されます。
+ `CopyObject` API オペレーションのサイズ制限よりも大きいオブジェクトは、[マルチパートアップロード copy コマンド](https://docs.aws.amazon.com/AmazonS3/latest/userguide/CopyingObjectsMPUapi.html)を使用する必要があります。
+ AWS マネジメントコンソール を使用していくつかの操作を実行するとき、オブジェクトのサイズが 16 MB より大きい場合、Amazon S3 はマルチパートアップロードを使用します。

## チェックサム方式
<a name="ChecksumMethods"></a>

オブジェクトをアップロードした後、チェックサム値を取得し、事前計算済みまたは以前に保存された同じチェックサムアルゴリズムタイプのチェックサム値と比較できます。次の例は、データの整合性を検証するために使用できるチェックサム計算方法を示しています。

### S3 コンソールの使用
<a name="CheckObjectIntegrityConsole"></a>

コンソールの使用方法およびオブジェクトのアップロード時に使用するチェックサムアルゴリズムの指定方法の詳細については、「[オブジェクトのアップロード](upload-objects.md)」および「[チュートリアル: チェックサムを追加して Amazon S3 のデータの整合性をチェックする](https://aws.amazon.com/getting-started/hands-on/amazon-s3-with-additional-checksums/?ref=docs_gateway/amazons3/checking-object-integrity.html)」を参照してください。

### AWS SDK の使用
<a name="CheckObjectIntegritySDK"></a>

次の例は、AWS SDK を使用して、マルチパートアップロードで大きなファイルをアップロードする方法、大きなファイルをダウンロードする方法、およびマルチパートアップロードファイルを検証する方法を示しています。ファイル検証にはすべて SHA-256 を使用しています。

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

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

```
    import software.amazon.awssdk.auth.credentials.AwsCredentials;
    import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
    import software.amazon.awssdk.core.ResponseInputStream;
    import software.amazon.awssdk.core.sync.RequestBody;
    import software.amazon.awssdk.regions.Region;
    import software.amazon.awssdk.services.s3.S3Client;
    import software.amazon.awssdk.services.s3.model.AbortMultipartUploadRequest;
    import software.amazon.awssdk.services.s3.model.ChecksumAlgorithm;
    import software.amazon.awssdk.services.s3.model.ChecksumMode;
    import software.amazon.awssdk.services.s3.model.CompleteMultipartUploadRequest;
    import software.amazon.awssdk.services.s3.model.CompleteMultipartUploadResponse;
    import software.amazon.awssdk.services.s3.model.CompletedMultipartUpload;
    import software.amazon.awssdk.services.s3.model.CompletedPart;
    import software.amazon.awssdk.services.s3.model.CreateMultipartUploadRequest;
    import software.amazon.awssdk.services.s3.model.CreateMultipartUploadResponse;
    import software.amazon.awssdk.services.s3.model.GetObjectAttributesRequest;
    import software.amazon.awssdk.services.s3.model.GetObjectAttributesResponse;
    import software.amazon.awssdk.services.s3.model.GetObjectRequest;
    import software.amazon.awssdk.services.s3.model.GetObjectResponse;
    import software.amazon.awssdk.services.s3.model.GetObjectTaggingRequest;
    import software.amazon.awssdk.services.s3.model.ObjectAttributes;
    import software.amazon.awssdk.services.s3.model.PutObjectTaggingRequest;
    import software.amazon.awssdk.services.s3.model.Tag;
    import software.amazon.awssdk.services.s3.model.Tagging;
    import software.amazon.awssdk.services.s3.model.UploadPartRequest;
    import software.amazon.awssdk.services.s3.model.UploadPartResponse;
     
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.nio.ByteBuffer;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.ArrayList;
    import java.util.Base64;
    import java.util.List;
     
    public class LargeObjectValidation {
        private static String FILE_NAME = "sample.file";
        private static String BUCKET = "sample-bucket";
        //Optional, if you want a method of storing the full multipart object checksum in S3.
        private static String CHECKSUM_TAG_KEYNAME = "fullObjectChecksum";
        //If you have existing full-object checksums that you need to validate against, you can do the full object validation on a sequential upload.
        private static String SHA256_FILE_BYTES = "htCM5g7ZNdoSw8bN/mkgiAhXt5MFoVowVg+LE9aIQmI=";
        //Example Chunk Size - this must be greater than or equal to 5MB.
        private static int CHUNK_SIZE = 5 * 1024 * 1024;
     
        public static void main(String[] args) {
            S3Client s3Client = S3Client.builder()
                    .region(Region.US_EAST_1)
                    .credentialsProvider(new AwsCredentialsProvider() {
                        @Override
                        public AwsCredentials resolveCredentials() {
                            return new AwsCredentials() {
                                @Override
                                public String accessKeyId() {
                                    return Constants.ACCESS_KEY;
                                }
     
                                @Override
                                public String secretAccessKey() {
                                    return Constants.SECRET;
                                }
                            };
                        }
                    })
                    .build();
            uploadLargeFileBracketedByChecksum(s3Client);
            downloadLargeFileBracketedByChecksum(s3Client);
            validateExistingFileAgainstS3Checksum(s3Client);
        }
     
        public static void uploadLargeFileBracketedByChecksum(S3Client s3Client) {
            System.out.println("Starting uploading file validation");
            File file = new File(FILE_NAME);
            try (InputStream in = new FileInputStream(file)) {
                MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
                CreateMultipartUploadRequest createMultipartUploadRequest = CreateMultipartUploadRequest.builder()
                        .bucket(BUCKET)
                        .key(FILE_NAME)
                        .checksumAlgorithm(ChecksumAlgorithm.SHA256)
                        .build();
                CreateMultipartUploadResponse createdUpload = s3Client.createMultipartUpload(createMultipartUploadRequest);
                List<CompletedPart> completedParts = new ArrayList<CompletedPart>();
                int partNumber = 1;
                byte[] buffer = new byte[CHUNK_SIZE];
                int read = in.read(buffer);
                while (read != -1) {
                    UploadPartRequest uploadPartRequest = UploadPartRequest.builder()
                            .partNumber(partNumber).uploadId(createdUpload.uploadId()).key(FILE_NAME).bucket(BUCKET).checksumAlgorithm(ChecksumAlgorithm.SHA256).build();
                    UploadPartResponse uploadedPart = s3Client.uploadPart(uploadPartRequest, RequestBody.fromByteBuffer(ByteBuffer.wrap(buffer, 0, read)));
                    CompletedPart part = CompletedPart.builder().partNumber(partNumber).checksumSHA256(uploadedPart.checksumSHA256()).eTag(uploadedPart.eTag()).build();
                    completedParts.add(part);
                    sha256.update(buffer, 0, read);
                    read = in.read(buffer);
                    partNumber++;
                }
                String fullObjectChecksum = Base64.getEncoder().encodeToString(sha256.digest());
                if (!fullObjectChecksum.equals(SHA256_FILE_BYTES)) {
                    //Because the SHA256 is uploaded after the part is uploaded; the upload is bracketed and the full object can be fully validated.
                    s3Client.abortMultipartUpload(AbortMultipartUploadRequest.builder().bucket(BUCKET).key(FILE_NAME).uploadId(createdUpload.uploadId()).build());
                    throw new IOException("Byte mismatch between stored checksum and upload, do not proceed with upload and cleanup");
                }
                CompletedMultipartUpload completedMultipartUpload = CompletedMultipartUpload.builder().parts(completedParts).build();
                CompleteMultipartUploadResponse completedUploadResponse = s3Client.completeMultipartUpload(
                        CompleteMultipartUploadRequest.builder().bucket(BUCKET).key(FILE_NAME).uploadId(createdUpload.uploadId()).multipartUpload(completedMultipartUpload).build());
                Tag checksumTag = Tag.builder().key(CHECKSUM_TAG_KEYNAME).value(fullObjectChecksum).build();
                //Optionally, if you need the full object checksum stored with the file; you could add it as a tag after completion.
                s3Client.putObjectTagging(PutObjectTaggingRequest.builder().bucket(BUCKET).key(FILE_NAME).tagging(Tagging.builder().tagSet(checksumTag).build()).build());
            } catch (IOException | NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            GetObjectAttributesResponse
                    objectAttributes = s3Client.getObjectAttributes(GetObjectAttributesRequest.builder().bucket(BUCKET).key(FILE_NAME)
                    .objectAttributes(ObjectAttributes.OBJECT_PARTS, ObjectAttributes.CHECKSUM).build());
            System.out.println(objectAttributes.objectParts().parts());
            System.out.println(objectAttributes.checksum().checksumSHA256());
        }
     
        public static void downloadLargeFileBracketedByChecksum(S3Client s3Client) {
            System.out.println("Starting downloading file validation");
            File file = new File("DOWNLOADED_" + FILE_NAME);
            try (OutputStream out = new FileOutputStream(file)) {
                GetObjectAttributesResponse
                        objectAttributes = s3Client.getObjectAttributes(GetObjectAttributesRequest.builder().bucket(BUCKET).key(FILE_NAME)
                        .objectAttributes(ObjectAttributes.OBJECT_PARTS, ObjectAttributes.CHECKSUM).build());
                //Optionally if you need the full object checksum, you can grab a tag you added on the upload
                List<Tag> objectTags = s3Client.getObjectTagging(GetObjectTaggingRequest.builder().bucket(BUCKET).key(FILE_NAME).build()).tagSet();
                String fullObjectChecksum = null;
                for (Tag objectTag : objectTags) {
                    if (objectTag.key().equals(CHECKSUM_TAG_KEYNAME)) {
                        fullObjectChecksum = objectTag.value();
                        break;
                    }
                }
                MessageDigest sha256FullObject = MessageDigest.getInstance("SHA-256");
                MessageDigest sha256ChecksumOfChecksums = MessageDigest.getInstance("SHA-256");
     
                //If you retrieve the object in parts, and set the ChecksumMode to enabled, the SDK will automatically validate the part checksum
                for (int partNumber = 1; partNumber <= objectAttributes.objectParts().totalPartsCount(); partNumber++) {
                    MessageDigest sha256Part = MessageDigest.getInstance("SHA-256");
                    ResponseInputStream<GetObjectResponse> response = s3Client.getObject(GetObjectRequest.builder().bucket(BUCKET).key(FILE_NAME).partNumber(partNumber).checksumMode(ChecksumMode.ENABLED).build());
                    GetObjectResponse getObjectResponse = response.response();
                    byte[] buffer = new byte[CHUNK_SIZE];
                    int read = response.read(buffer);
                    while (read != -1) {
                        out.write(buffer, 0, read);
                        sha256FullObject.update(buffer, 0, read);
                        sha256Part.update(buffer, 0, read);
                        read = response.read(buffer);
                    }
                    byte[] sha256PartBytes = sha256Part.digest();
                    sha256ChecksumOfChecksums.update(sha256PartBytes);
                    //Optionally, you can do an additional manual validation again the part checksum if needed in addition to the SDK check
                    String base64PartChecksum = Base64.getEncoder().encodeToString(sha256PartBytes);
                    String base64PartChecksumFromObjectAttributes = objectAttributes.objectParts().parts().get(partNumber - 1).checksumSHA256();
                    if (!base64PartChecksum.equals(getObjectResponse.checksumSHA256()) || !base64PartChecksum.equals(base64PartChecksumFromObjectAttributes)) {
                        throw new IOException("Part checksum didn't match for the part");
                    }
                    System.out.println(partNumber + " " + base64PartChecksum);
                }
                //Before finalizing, do the final checksum validation.
                String base64FullObject = Base64.getEncoder().encodeToString(sha256FullObject.digest());
                String base64ChecksumOfChecksums = Base64.getEncoder().encodeToString(sha256ChecksumOfChecksums.digest());
                if (fullObjectChecksum != null && !fullObjectChecksum.equals(base64FullObject)) {
                    throw new IOException("Failed checksum validation for full object");
                }
                System.out.println(fullObjectChecksum);
                String base64ChecksumOfChecksumFromAttributes = objectAttributes.checksum().checksumSHA256();
                if (base64ChecksumOfChecksumFromAttributes != null && !base64ChecksumOfChecksums.equals(base64ChecksumOfChecksumFromAttributes)) {
                    throw new IOException("Failed checksum validation for full object checksum of checksums");
                }
                System.out.println(base64ChecksumOfChecksumFromAttributes);
                out.flush();
            } catch (IOException | NoSuchAlgorithmException e) {
                //Cleanup bad file
                file.delete();
                e.printStackTrace();
            }
        }
     
        public static void validateExistingFileAgainstS3Checksum(S3Client s3Client) {
            System.out.println("Starting existing file validation");
            File file = new File("DOWNLOADED_" + FILE_NAME);
            GetObjectAttributesResponse
                    objectAttributes = s3Client.getObjectAttributes(GetObjectAttributesRequest.builder().bucket(BUCKET).key(FILE_NAME)
                    .objectAttributes(ObjectAttributes.OBJECT_PARTS, ObjectAttributes.CHECKSUM).build());
            try (InputStream in = new FileInputStream(file)) {
                MessageDigest sha256ChecksumOfChecksums = MessageDigest.getInstance("SHA-256");
                MessageDigest sha256Part = MessageDigest.getInstance("SHA-256");
                byte[] buffer = new byte[CHUNK_SIZE];
                int currentPart = 0;
                int partBreak = objectAttributes.objectParts().parts().get(currentPart).size();
                int totalRead = 0;
                int read = in.read(buffer);
                while (read != -1) {
                    totalRead += read;
                    if (totalRead >= partBreak) {
                        int difference = totalRead - partBreak;
                        byte[] partChecksum;
                        if (totalRead != partBreak) {
                            sha256Part.update(buffer, 0, read - difference);
                            partChecksum = sha256Part.digest();
                            sha256ChecksumOfChecksums.update(partChecksum);
                            sha256Part.reset();
                            sha256Part.update(buffer, read - difference, difference);
                        } else {
                            sha256Part.update(buffer, 0, read);
                            partChecksum = sha256Part.digest();
                            sha256ChecksumOfChecksums.update(partChecksum);
                            sha256Part.reset();
                        }
                        String base64PartChecksum = Base64.getEncoder().encodeToString(partChecksum);
                        if (!base64PartChecksum.equals(objectAttributes.objectParts().parts().get(currentPart).checksumSHA256())) {
                            throw new IOException("Part checksum didn't match S3");
                        }
                        currentPart++;
                        System.out.println(currentPart + " " + base64PartChecksum);
                        if (currentPart < objectAttributes.objectParts().totalPartsCount()) {
                            partBreak += objectAttributes.objectParts().parts().get(currentPart - 1).size();
                        }
                    } else {
                        sha256Part.update(buffer, 0, read);
                    }
                    read = in.read(buffer);
                }
                if (currentPart != objectAttributes.objectParts().totalPartsCount()) {
                    currentPart++;
                    byte[] partChecksum = sha256Part.digest();
                    sha256ChecksumOfChecksums.update(partChecksum);
                    String base64PartChecksum = Base64.getEncoder().encodeToString(partChecksum);
                    System.out.println(currentPart + " " + base64PartChecksum);
                }
     
                String base64CalculatedChecksumOfChecksums = Base64.getEncoder().encodeToString(sha256ChecksumOfChecksums.digest());
                System.out.println(base64CalculatedChecksumOfChecksums);
                System.out.println(objectAttributes.checksum().checksumSHA256());
                if (!base64CalculatedChecksumOfChecksums.equals(objectAttributes.checksum().checksumSHA256())) {
                    throw new IOException("Full object checksum of checksums don't match S3");
                }
     
            } catch (IOException | NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        }
    }
```

------

### REST API の使用
<a name="CheckObjectIntegrityREST"></a>

REST リクエストを送信して、チェックサムの値を持つオブジェクトをアップロードし、[PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) でデータの整合性を検証できます。[GetObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) または [HeadObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html) を使用して、オブジェクトのチェックサムの値を取得することもできます。

### AWS CLI の使用
<a name="CheckObjectIntegrityCLI"></a>

単一のオペレーションで、最大 5 GB のオブジェクトをアップロードする `PUT` リクエストを送信できます。詳細については、「*AWS CLI コマンドリファレンス*」の [https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html#examples](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html#examples) を参照してください。また、[https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html](https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html) と [https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html](https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html) を使用して、すでにアップロードされたオブジェクトのチェックサムを取得し、データの整合性を検証することもできます。

詳細については、「AWS Command Line Interface ユーザーガイド」の「[Amazon S3 CLI のよくある質問](https://docs.aws.amazon.com/cli/latest/topic/s3-faq.html)」を参照してください。**

## オブジェクトをアップロードするときに Content-MD5 を使用する
<a name="checking-object-integrity-md5"></a>

アップロード後にオブジェクトの整合性を検証するもう 1 つの方法は、アップロード時にオブジェクトの MD5 ダイジェストを指定することです。オブジェクトの MD5 ダイジェストを計算した場合、`Content-MD5` ヘッダーを使用することで、`PUT` コマンドでダイジェストを指定できます。

オブジェクトをアップロードした後、Amazon S3 はオブジェクトの MD5 ダイジェストを計算し、指定した値と比較します。リクエストは、2 つのダイジェストが一致した場合にのみ成功します。

MD5 ダイジェストを指定する必要はありませんが、アップロードプロセスの一環としてオブジェクトの整合性を検証するために使用できます。

## Content-MD5 と ETag を使用して、アップロードされたオブジェクトを検証する
<a name="checking-object-integrity-etag-and-md5"></a>

オブジェクトのエンティティタグ (ETag) は、そのオブジェクトの特定のバージョンを表します。ETag は、オブジェクトのコンテンツに加えられた変更のみを反映し、メタデータに加えられた変更は反映しないことに注意してください。オブジェクトのメタデータのみが変更された場合、ETag は同じままです。

オブジェクトによっては、オブジェクトの ETag がオブジェクトデータの MD5 ダイジェストである場合があります。
+ オブジェクトが `PutObject`、`PostObject`、または `CopyObject` オペレーションによって、または AWS マネジメントコンソール を介して作成され、そのオブジェクトがプレーンテキストか、Amazon S3 マネージドキーを使用したサーバー側の暗号化 (SSE-S3) によって暗号化されている場合、そのオブジェクトの ETag は、オブジェクトデータの MD5 ダイジェストです。
+ オブジェクトが `PutObject`、`PostObject`、または `CopyObject` オペレーションによって、または AWS マネジメントコンソール を介して作成され、そのオブジェクトがお客様が用意したキーを使用したサーバー側の暗号化 (SSE-C) または AWS Key Management Service (AWS KMS) キーを使用したサーバー側の暗号化 (SSE-KMS) によって暗号化されている場合、そのオブジェクトの ETag は、オブジェクトデータの MD5 ダイジェストではありません。
+ オブジェクトがマルチパートアップロードのプロセスまたは `UploadPartCopy` オペレーションによって作成された場合、暗号化の方法に関係なく、オブジェクトの ETag は MD5 ダイジェストではありません。オブジェクトが 16 MB より大きい場合、AWS マネジメントコンソール はそのオブジェクトをマルチパートアップロードとしてアップロードまたはコピーするため、ETag は MD5 ダイジェストではありません。

ETag がオブジェクトの `Content-MD5` ダイジェストであるオブジェクトの場合、オブジェクトの ETag 値を計算済みまたは以前に保存した `Content-MD5` ダイジェストと比較できます。

## 追跡チェックサムの使用
<a name="trailing-checksums"></a>

Amazon S3 にラージオブジェクトをアップロードするときには、オブジェクトの事前計算されたチェックサムを指定するか、AWS SDK を使用して、チャンクアップロード用の追跡チェックサムを自動的に作成できます。追跡チェックサムを使用する場合、Amazon S3 は指定したアルゴリズムを使用してチェックサム値を自動的に生成し、オブジェクトのアップロード時に、チャンクアップロードでオブジェクトの整合性を検証します。

AWS SDK を使用しているときに追跡チェックサムを作成するには、`ChecksumAlgorithm` パラメータに任意のアルゴリズムを指定します。SDK は、そのアルゴリズムを使用してオブジェクト (またはオブジェクトパート) のチェックサム値を計算し、チャンクアップロードリクエストの最後に自動的に追加します。この動作により、Amazon S3 はデータの検証とアップロードを単一のパスで実行するため、時間を節約できます。

**重要**  
S3 オブジェクト Lambda を使用している場合、S3 オブジェクト Lambda へのすべてのリクエストは、`s3` の代わりに `s3-object-lambda` を使用して署名されます。この動作は、追跡チェックサム値のシグネチャに影響します。S3 Object Lambda, の詳細については、「[S3 Object Lambda を使用したオブジェクトの変換](transforming-objects.md)」を参照してください。

### 末尾のチェックサムヘッダー
<a name="trailing-checksums-headers"></a>

チャンクコンテンツエンコードのリクエストを行うために、Amazon S3 では、リクエストを正しく解析するためにクライアントサーバーに複数のヘッダーを含める必要があります。クライアントサーバーには、次のヘッダーを含める必要があります。
+ ** `x-amz-decoded-content-length`:**このヘッダーは、リクエストとともに Amazon S3 にアップロードされる実際のデータのプレーンテキストサイズを示します。
+ **`x-amz-content-sha256`:** このヘッダーは、リクエストに含まれるチャンクアップロードのタイプを示します。チェックサムが末尾にあるチャンクアップロードの場合、ヘッダー値は、ペイロード署名を使用しないリクエストの場合は `STREAMING-UNSIGNED-PAYLOAD-TRAILER`、SigV4 ペイロード署名を使用するリクエストの場合は `STREAMING-AWS4-HMAC-SHA256-PAYLOAD-TRAILER` です。(署名付きペイロードの実装の詳細については、「[Signature calculations for the authorization header: Transferring a payload in multiple chunks](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html)」を参照してください。)
+ **`x-amz-trailer`:** このヘッダーは、リクエストの末尾のヘッダーの名前を示します。末尾のチェックサムが存在する場合 (AWS SDK がエンコードされたリクエスト本文にチェックサムを追加する場合)、`x-amz-trailer` ヘッダー値には `x-amz-checksum-` プレフィックスが含まれ、アルゴリズム名で終わります。現在、次の `x-amz-trailer` 値がサポートされています。
  + `x-amz-checksum-crc32`
  + `x-amz-checksum-crc32c`
  + `x-amz-checksum-crc64nvme`
  + `x-amz-checksum-sha1`
  + `x-amz-checksum-sha256`

**注記**  
リクエストには、チャンク化された値を含む `Content-Encoding` ヘッダーを含めることもできます。このヘッダーは必須ではありませんが、このヘッダーを含めることで、エンコードされたデータを送信する際の HTTP プロキシの問題を最小限に抑えることができます。リクエストに別の `Content-Encoding` ヘッダー (gzip など) が存在する場合、`Content-Encoding` ヘッダーには、エンコードのカンマ区切りリストにチャンク化された値が含まれます。例えば、`Content-Encoding: aws-chunked, gzip`。

### チャンクパーツ
<a name="trailing-checksums-chunks"></a>

チャンクエンコードを使用して Amazon S3 にオブジェクトをアップロードする場合、アップロードリクエストには次のタイプのチャンク (リストされた順序でフォーマット) が含まれます。
+ **オブジェクト本体のチャンク:** チャンクアップロードリクエストに関連付けられた本体チャンクは、1 つ、複数、またはゼロの場合があります。
+ **完了チャンク:** チャンクアップロードリクエストに関連付けられた本体チャンクは、1 つ、複数、またはゼロの場合があります。
+ **末尾チャンク:** 末尾のチェックサムは、完了チャンクの後に表示されます。末尾のチャンクは 1 つだけ許可されます。

**注記**  
 チャンクアップロードはすべて、リクエストの終了を示すために、最後の CRLF (`\r\n` など) で終わる必要があります。

チャンク形式の例については、「[例: 末尾にチェックサムが付いたチャンクアップロード](#example-chunked-uploads-trailing)」を参照してください。

#### オブジェクト本体のチャンク
<a name="trailing-checksums-object-body-chunks"></a>

オブジェクト本体のチャンクは、S3 にアップロードされる実際のオブジェクトデータを含むチャンクです。これらのチャンクには、一貫したサイズと形式の制約があります。

##### オブジェクト本体のチャンクサイズ
<a name="trailing-checksums-object-body-chunks-size"></a>

これらのチャンクには、少なくとも 8,192 バイト (または 8 KiB) のオブジェクトデータが含まれている必要があります。ただし、最後の本体チャンクは小さい場合があります。明示的な最大チャンクサイズはありませんが、すべてのチャンクが 5 GB の最大アップロードサイズより小さくなることが予想されます。チャンクサイズは、クライアントサーバーの実装に応じてチャンクごとに異なる場合があります。

##### オブジェクト本体のチャンク形式
<a name="trailing-checksums-object-body-chunks-format"></a>

オブジェクト本体のチャンクは、オブジェクト本体チャンク内のバイト数の 16 進エンコードで始まり、CRLF (キャリッジリターンラインフィード)、そのチャンクのオブジェクトバイト、および別の CRLF が続きます。

例えば、次のようになります。

```
hex-encoding-of-object-bytes-in-chunk\r\n
chunk-object-bytes\r\n
```

ただし、チャンクが署名されている場合、オブジェクト本体のチャンクは別の形式に従います。この形式では、署名がセミコロン区切り文字でチャンクサイズに追加されます。例えば、次のようになります。

```
hex-encoding-of-object-bytes-in-chunk;chunk-signature\r\n
 chunk-object-bytes\r\n
```

チャンク署名の詳細については、「[Signature calculations for the Authorization Header: Transferring a payload in multiple chunks (AWS Signature Version 4)](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html)」を参照してください。チャンクの形式の詳細については、*RFC Editor* ウェブサイトの「[Chunked transfer encoding](https://www.rfc-editor.org/rfc/rfc9112#name-chunked-transfer-coding)」を参照してください。

#### 完了チャンク
<a name="trailing-checksums-completion-chunks"></a>

完了チャンクは、すべてのチャンクアップロードの最後のオブジェクト本体チャンクである必要があります。完了チャンクの形式は本体チャンクに似ていますが、常に 0 バイトのオブジェクトデータが含まれています。(オブジェクトデータの 0 バイトは、すべてのデータがアップロードされたことを示します。) チャンクアップロードには、次のような形式に従って、最後のオブジェクト本体チャンクとして完了チャンクを含める必要があります。

```
0\r\n
```

ただし、コンテンツエンコードリクエストでペイロード署名が使用されている場合、代わりに次の形式に従います。

```
0;chunk-signature\r\n
```

#### トレーラーチャンク
<a name="trailing-checksums-trailer-chunks"></a>

トレーラーチャンクは、すべての S3 アップロードリクエストの計算されたチェックサムを保持します。トレーラーチャンクには、ヘッダー名フィールド 1 つとヘッダー値フィールド 1 つの 2 つのフィールドが含まれます。アップロードリクエストのヘッダー名フィールドは、`x-amz-trailer` リクエストヘッダーに渡された値と一致する必要があります。例えば、リクエストに `x-amz-trailer: x-amz-checksum-crc32` が含まれており、トレーラーチャンクにヘッダー名 `x-amz-checksum-sha1` がある場合、リクエストは失敗します。トレーラーチャンクの値フィールドには、そのオブジェクトのビッグエンディアンチェックサム値の base64 エンコードが含まれます。(ビッグエンディアンの順序では、最上位バイトのデータが最小のメモリアドレスに、最下位バイトが最大メモリアドレスに保存されます)。このチェックサムの計算に使用されるアルゴリズムは、ヘッダー名のサフィックス (例: `crc32`) と同じです。

##### トレーラーチャンク形式
<a name="trailing-checksums-trailer-chunk-format"></a>

トレーラーチャンクは、署名なしペイロードリクエストに次の形式を使用します。

```
x-amz-checksum-lowercase-checksum-algorithm-name:base64-checksum-value\n\r\n\r\n
```

[SigV4 署名付きペイロード](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming-trailers.html)を使用したリクエストの場合、トレーラーチャンクには、トレーラーチャンクの後にトレーラー署名が含まれます。

```
trailer-checksum\n\r\n
trailer-signature\r\n
```

また、CRLF を base64 チェックサム値の末尾に直接追加することもできます。例えば、次のようになります。

```
x-amz-checksum-lowercase-checksum-algorithm-name:base64-checksum-value\r\n\r\n
```

#### 例: 末尾にチェックサムが付いたチャンクアップロード
<a name="example-chunked-uploads-trailing"></a>

Amazon S3 は、`PutObject` に `aws-chunked` コンテンツエンコードを使用するチャンクアップロードと、末尾のチェックサムを含む `UploadPart` リクエストをサポートします。

**Example 1 – 末尾に CRC-32 チェックサムが付いた署名なしチャンク `PutObject` リクエスト**  

 以下は、末尾に CRC-32 チェックサムが付いたチャンク `PutObject` リクエストの例です。この例では、クライアントは 3 つの署名なしチャンクに 17 KB のオブジェクトをアップロードし、`x-amz-checksum-crc32` ヘッダーを使用して末尾に CRC-32 チェックサムチャンクを追加します。

```
PUT /Key+ HTTP/1.1
Host: amzn-s3-demo-bucket
Content-Encoding: aws-chunked
x-amz-decoded-content-length: 17408
x-amz-content-sha256: STREAMING-UNSIGNED-PAYLOAD-TRAILER
x-amz-trailer: x-amz-checksum-crc32

2000\r\n                                   // Object body chunk 1 (8192 bytes)
object-bytes\r\n
2000\r\n                                   // Object body chunk 2 (8192 bytes)
object-bytes\r\n
400\r\n                                    // Object body chunk 3 (1024 bytes)
object-bytes\r\n
0\r\n                                      // Completion chunk
x-amz-checksum-crc32:YABb/g==\n\r\n\r\n    // Trailer chunk (note optional \n character)
\r\n                                         // CRLF
```

レスポンスの例を次に示します。

```
HTTP/1.1 200
ETag: ETag
x-amz-checksum-crc32: YABb/g==
```

**注記**  
 チェックサム値の最後にあるラインフィード `\n` の使用は、クライアントによって異なる場合があります。

**Example 2 – 末尾に CRC-32 (`CRC32`) チェックサムが付いた SigV4 署名付きチャンク `PutObject` リクエスト**  

以下は、末尾に CRC-32 チェックサムが付いたチャンク `PutObject` リクエストの例です。このリクエストは SigV4 ペイロード署名を使用します。この例では、クライアントは 3 つの署名付きチャンクに 17 KB のオブジェクトをアップロードします。`object body` チャンクに加えて、`completion chunk` と `trailer chunk` も署名されています。

```
PUT /Key+ HTTP/1.1
Host: amzn-s3-demo-bucket.s3.amazonaws.com
Content-Encoding: aws-chunked
x-amz-decoded-content-length: 17408
x-amz-content-sha256: STREAMING-AWS4-HMAC-SHA256-PAYLOAD-TRAILER
x-amz-trailer: x-amz-checksum-crc32
		
authorization-code                            // SigV4 headers authorization

2000;chunk-signature=signature-value...\r\n   // Object body chunk 1 (8192 bytes)
object-bytes\r\n
2000;chunk-signature\r\n                      // Object body chunk 2 (8192 bytes)
object-bytes\r\n
400;chunk-signature\r\n                       // Object body chunk 3 (1024 bytes)
object-bytes\r\n
0;chunk-signature\r\n                         // Completion chunk
x-amz-checksum-crc32:YABb/g==\n\r\n            // Trailer chunk (note optional \n character)
trailer-signature\r\n
\r\n                                           // CRLF
```

レスポンスの例を次に示します。

```
HTTP/1.1 200
ETag: ETag
x-amz-checksum-crc32: YABb/g==
```

# Amazon S3 で保管中のデータのオブジェクトの整合性を確認する
<a name="checking-object-integrity-at-rest"></a>

Amazon S3 に保存されているデータセットの内容を検証する必要がある場合、S3 バッチオペレーション [[チェックサムを計算]](https://docs.aws.amazon.com//AmazonS3/latest/userguide/batch-ops-compute-checksums.html) オペレーションは、保管中のオブジェクトのフルオブジェクトチェックサムと複合チェックサムの両方を計算します。**[チェックサムを計算]** オペレーションでは、バッチオペレーションを使用してオブジェクトグループのチェックサム値を非同期的に計算し、統合された整合性レポートを自動的に生成します。データの新しいコピーを作成したり、データを復元またはダウンロードしたりすることはありません。

**[チェックサムを計算]** オペレーションを使用すると、1 回のジョブリクエストで数十億のオブジェクトを効率的に検証できます。**[チェックサムを計算]** ジョブリクエストごとに、S3 はチェックサム値を計算し、自動生成された整合性レポート (完了レポートとも呼ばれます) に含めます。その後、完了レポートを使用してデータセットの整合性を検証できます。

**[チェックサムを計算]** オペレーションは、ストレージクラスやオブジェクトサイズに関係なく、S3 に保存されているすべてのオブジェクトで機能します。オブジェクトをデータ保存のベストプラクティスとして検証する必要がある場合でも、コンプライアンス要件を満たす必要がある場合でも、**[チェックサムを計算]** オペレーションは、保管中のチェックサム計算を実行することで、データ検証に必要なコスト、時間、労力を削減します。**[チェックサムを計算]** の料金については、「[Amazon S3 の料金](https://aws.amazon.com/s3/pricing/)」の **[管理とインサイト]** タブを参照してください。

次に、生成された完了レポートの出力を使用して、データベースに保存したチェックサム値と比較し、データセットが時間の経過とともにそのまま残っていることを確認できます。このアプローチは、ビジネスとコンプライアンスのニーズに合わせてエンドツーエンドのデータ整合性を維持するのに役立ちます。例えば、**[チェックサムを計算]** オペレーションを使用して、S3 Glacier ストレージクラスに保存されているオブジェクトのリストを年次セキュリティ監査に送信できます。さらに、サポートされているチェックサムアルゴリズムの範囲により、アプリケーションで使用されているアルゴリズムとの継続性を維持できます。

## サポートされているチェックサムアルゴリズムの使用
<a name="using-additional-checksums-rest"></a>

保管中のデータについては、サポートされているチェックサムアルゴリズムのいずれかを使用して、チェックサムを計算できます。
+ CRC-64/NVME (`CRC64NVME`): フルオブジェクトのチェックサムタイプのみをサポートします。
+ CRC-32 (`CRC32`): フルオブジェクトおよび複合チェックサムタイプの両方をサポートします。
+ CRC-32C (`CRC32C`): フルオブジェクトおよび複合チェックサムタイプの両方をサポートします。
+ SHA-1 (`SHA1`): フルオブジェクトおよび複合チェックサムタイプの両方をサポートします。
+ SHA-256 (`SHA256`): フルオブジェクトおよび複合チェックサムタイプの両方をサポートします。
+ MD5 (`MD5`): フルオブジェクトおよび複合チェックサムタイプの両方をサポートします。

## **[チェックサムを計算]** の使用
<a name="Compute-checksums"></a>

Amazon S3 に保存されているオブジェクトの場合、S3 バッチオペレーションで **[チェックサムを計算]** オペレーションを使用して、保管中のデータの内容を確認できます。Amazon S3 コンソール、AWS Command Line Interface (AWS CLI)、REST API、AWS SDK を使用して [Compute checksum バッチオペレーションジョブを作成](https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-create-job.html)できます。**[チェックサムを計算]** ジョブが完了すると、完了レポートが表示されます。完了レポートの使用方法については、「[ジョブステータスと完了レポートの追跡](https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-job-status.html)」を参照してください。

**[チェックサムを計算]** ジョブを作成する前に、S3 バッチオペレーション AWS Identity and Access Management (IAM) ロールを作成し、ユーザーに代わってアクションを実行するための Amazon S3 のアクセス許可を付与する必要があります。マニフェストファイルを読み取って完了レポートを S3 バケットに書き込むためのアクセス許可を付与する必要があります。詳細については、「[チェックサムの計算](batch-ops-compute-checksums.md)」を参照してください。

### S3 コンソールの使用
<a name="Compute-checksum-console"></a>

****[チェックサムを計算]** オペレーションを使用するには**

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

1. ページ上部にあるナビゲーションバーで、現在表示されている AWS リージョン の名前をクリックします。次に、ジョブを作成するリージョンを選択します。
**注記**  
コピーオペレーションの場合は、コピー先バケットと同じリージョンにジョブを作成する必要があります。その他すべてのオペレーションの場合は、マニフェスト内のオブジェクトと同じリージョンにジョブを作成する必要があります。

1. Amazon S3 コンソールのナビゲーションペインで **[バッチオペレーション]** を選択します。

1. **[ジョブの作成]** を選択します。

1. ジョブを作成する AWS リージョン を確認します。
**注記**  
コピーオペレーションの場合は、コピー先バケットと同じリージョンにジョブを作成する必要があります。その他すべてのオペレーションの場合は、マニフェスト内のオブジェクトと同じリージョンにジョブを作成する必要があります。

1. [**マニフェストの形式**] で、使用するマニフェストオブジェクトのタイプを選択します。
   + **[S3 インベントリレポート (manifest.json)]** を選択した場合は、`manifest.json` オブジェクトへのパスを入力し、特定のオブジェクトバージョンを使用する場合は **[マニフェストオブジェクトのバージョン ID]** (オプション) を入力します。または、**[S3 を参照]** を選択し、マニフェスト JSON ファイルを選択できます。これにより、すべてのマニフェストオブジェクトのフィールドエントリが自動入力されます。
   + **[CSV]** を選択した場合は、マニフェストのロケーションタイプを選択し、CSV 形式のマニフェストオブジェクトへのパスを入力するか、**[S3 を参照]** を選択してマニフェストオブジェクトを選択します。マニフェストオブジェクトは、コンソールで説明される形式に従う必要があります。マニフェストオブジェクトの特定のバージョンを使用する場合は、オブジェクトバージョン ID を指定することもできます。
   + **[S3 レプリケーション設定を使用してマニフェストを作成]** を選択すると、レプリケーション設定を使用してオブジェクトのリストが生成され、オプションで、選択した送信先に保存されます。レプリケーション設定を使用してマニフェストを生成する場合、使用できるオペレーションは **[レプリケート]** のみです。

1. [**次へ**] を選択します。

1. **[オペレーション]** で **[チェックサムを計算]** オペレーションを選択し、マニフェストにリストされているすべてのオブジェクトのチェックサムを計算します。ジョブの **[チェックサムタイプ]** と **[チェックサム関数]** を選択します。その後、**[Next]** を選択します。

1. **[追加のオプションを設定]** に情報を入力して、**[次へ]** を選択します。

1. **[追加のオプションを設定]** ページで、**[チェックサムを計算]** ジョブの情報を入力します。
**注記**  
**[完了レポート]** で、確認ステートメントを確認します。この確認ステートメントは、完了レポートにチェックサム値が含まれていることを理解していることを確認します。チェックサム値は、Amazon S3 に保存されているデータの整合性を検証するために使用されます。したがって、完了レポートは慎重に共有する必要があります。また、[チェックサムを計算] リクエストを作成し、外部アカウント所有者のバケットロケーションを指定して完了レポートを保存する場合は、外部バケット所有者の AWS アカウント ID を必ず指定してください。

1. [**次へ**] を選択します。

1. **[確認]** ページで、設定を確認して確定します。

1. (オプション) 変更する必要がある場合は、**[戻る]** を選択して前のページに戻るか、**[編集]** を選択して特定のステップを更新します。

1. 変更を確認したら、**[ジョブの作成]** を選択します。

**すべての **[チェックサムを計算]** リクエストの進行状況を一覧表示およびモニタリングするには**

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

1. 左のナビゲーションペインで、[**バッチ操作**] を選択します。

1. **[バッチオペレーション]** ページで、ジョブの優先度、ジョブ完了率、オブジェクトの合計など、ジョブの詳細を確認できます。

1. 特定の **[チェックサムを計算]** ジョブを管理またはクローンする場合は、**[ジョブ ID]** をクリックして追加のジョブ情報を確認します。

1. 特定の **[チェックサムを計算]** ジョブページで、ジョブの詳細を確認します。

各バッチオペレーションジョブは、異なる [[ジョブステータス]](https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-job-status.html#batch-ops-job-status-table) で進行します。S3 コンソールで [AWS CloudTrail イベントを有効](https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-cloudtrail-logging-for-s3.html)にして、ジョブの状態の変化に関するアラートを受信することもできます。アクティブなジョブについては、**[ジョブの詳細]** ページで実行中のジョブと完了率を確認できます。

### AWS SDK の使用
<a name="Compute-checksum-sdk"></a>

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

**Example 例: **[チェックサムを計算]** ジョブの作成**  
次の例は、**[チェックサムを計算]** ジョブ (**[ジョブの作成]** リクエストの一部として) を作成する方法と、マニフェストを指定する方法を示しています。  

```
// Required parameters
String accountId = "111122223333";
String roleArn = "arn:aws:iam::111122223333:role/BatchOperations";
String manifestArn = "arn:aws:s3:::my_manifests/manifest.csv";
String manifestEtag = "60e460c9d1046e73f7dde5043ac3ae85";
String reportBucketArn = "arn:aws:s3:::amzn-s3-demo-completion-report-bucket";
String reportExpectedBucketOwner = "111122223333";
String reportPrefix = "demo-report";

// Job Operation
S3ComputeObjectChecksumOperation s3ComputeObjectChecksum = S3ComputeObjectChecksumOperation.builder()
    .checksumAlgorithm(ComputeObjectChecksumAlgorithm.CRC64)
    .checksumType(ComputeObjectChecksumType.COMPOSITE)
    .build();

JobOperation operation = JobOperation.builder()
    .s3ComputeObjectChecksum(s3ComputeObjectChecksum)
    .build();

// Job Manifest
JobManifestLocation location = JobManifestLocation.builder()
    .eTag(manifestEtag)
    .objectArn(manifestArn)
    .build();

JobManifestSpec spec = JobManifestSpec.builder()
    .format(JobManifestFormat.S3_BATCH_OPERATIONS_CSV_20180820)
    .fields(Arrays.asList(JobManifestFieldName.BUCKET, JobManifestFieldName.KEY))
    .build();

JobManifest manifest = JobManifest.builder()
    .location(location)
    .spec(spec)
    .build();

// Completion Report
JobReport report = JobReport.builder()
    .bucket(reportBucketArn)
    .enabled(true) // Must be true
    .expectedBucketOwner(reportExpectedBucketOwner)
    .format(JobReportFormat.REPORT_CSV_20180820)
    .prefix(reportPrefix)
    .reportScope(JobReportScope.ALL_TASKS)
    .build();

// Create Job Request
CreateJobRequest request = CreateJobRequest.builder()
    .accountId(accountId)
    .confirmationRequired(false)
    .manifest(manifest)
    .operation(operation)
    .priority(10)
    .report(report)
    .roleArn(roleArn);

// Create the client
S3ControlClient client = S3ControlClient.builder()
    .credentialsProvider(new ProfileCredentialsProvider())
    .region(Region.US_EAST_1)
    .build();

// Send the request
try {
    CreateJobResponse response = client.createJob(request);
    System.out.println(response);    
} catch (AwsServiceException e) {
    System.out.println("AwsServiceException: " + e.getMessage());
    throw new RuntimeException(e);
} catch (SdkClientException e) {
    System.out.println("SdkClientException: " + e.getMessage());
    throw new RuntimeException(e);
}
```

**Example 例: **[チェックサムを計算]** ジョブの詳細の表示**  
次の例は、ジョブ ID を指定して、**[チェックサムを計算]** ジョブリクエストのジョブの詳細 (ジョブの完了率など) を表示する方法を示しています。  

```
DescribeJobRequest request = DescribeJobRequest.builder()
        .accountId("1234567890")
        .jobId("a16217a1-e082-48e5-b04f-31fac3a66b13")
        .build();
```

------

### の使用AWS CLI
<a name="Compute-checksum-cli"></a>

[https://docs.aws.amazon.com/cli/latest/reference/s3control/create-job.html](https://docs.aws.amazon.com/cli/latest/reference/s3control/create-job.html) コマンドを使用して、新しいバッチオペレーションジョブを作成し、オブジェクトのリストを指定できます。次に、チェックサムアルゴリズムとチェックサムタイプ、および **[チェックサムを計算]** レポートを保存する送信先バケットを指定します。次の例では、S3 が AWS アカウント *111122223333* に生成したマニフェストを使用して S3 バッチレプリケーションの **[チェックサムを計算]** ジョブを作成します。

このコマンドを使用するには、*ユーザー入力プレースホルダー*を独自の情報に置き換えます。

```
aws s3control create-job \
    --account-id 111122223333 \
    --manifest '{"Spec":{"Format":"S3BatchOperations_CSV_20180820","Fields":["Bucket","Key"]},"Location":{"ObjectArn":"arn:aws:s3:::my-manifest-bucket/manifest.csv","ETag":"e0e8bfc50e0f0c5d5a1a5f0e0e8bfc50"}}' \
    --manifest-generator '{
        "S3JobManifestGenerator": {
          "ExpectedBucketOwner": "111122223333",
          "SourceBucket": "arn:aws:s3:::amzn-s3-demo-source-bucket",
          "EnableManifestOutput": true,
          "ManifestOutputLocation": {
            "ExpectedManifestBucketOwner": "111122223333",
            "Bucket": "arn:aws:s3:::amzn-s3-demo-manifest-bucket",
            "ManifestPrefix": "prefix",
            "ManifestFormat": "S3InventoryReport_CSV_20211130"
          },
          "Filter": {
            "CreatedAfter": "2023-09-01",
            "CreatedBefore": "2023-10-01",
            "KeyNameConstraint": {
              "MatchAnyPrefix": [
                "prefix"
              ],
              "MatchAnySuffix": [
                "suffix"
              ]
            },
            "ObjectSizeGreaterThanBytes": 100,
            "ObjectSizeLessThanBytes": 200,
            "MatchAnyStorageClass": [
              "STANDARD",
              "STANDARD_IA"
            ]
          }
        }
      }' \
    --operation '{"S3ComputeObjectChecksum":{"ChecksumAlgorithm":"CRC64NVME","ChecksumType":"FULL_OBJECT"}}' \
    --report '{"Bucket":"arn:aws:s3:::my-report-bucket","Format":"Report_CSV_20180820","Enabled":true,"Prefix":"batch-op-reports/","ReportScope":"AllTasks","ExpectedBucketOwner":"111122223333"}' \
    --priority 10 \
    --role-arn arn:aws:iam::123456789012:role/S3BatchJobRole \
    --client-request-token 6e023a7e-4820-4654-8c81-7247361aeb73 \
    --description "Compute object checksums" \
    --region us-west-2
```

**[チェックサムを計算]** ジョブを送信すると、ジョブ ID がレスポンスとして受信され、S3 バッチオペレーションのリストページに表示されます。Amazon S3 はオブジェクトのリストを処理し、各オブジェクトのチェックサムを計算します。ジョブが完了すると、S3 は指定された送信先に統合された **[チェックサムを計算]** レポートを提供します。

**[チェックサムを計算]** ジョブの進行状況をモニタリングするには、[https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3control/describe-job.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3control/describe-job.html) コマンドを使用します。このコマンドは、指定されたバッチオペレーションジョブのステータスをチェックします。このコマンドを使用するには、*ユーザー入力プレースホルダー*を独自の情報に置き換えます。

例えば、次のようになります。

```
aws s3control describe-job --account-id 111122223333 --job-id 1234567890abcdef0
```

すべての **[アクティブ]** および **[完了]** バッチオペレーションジョブの[リストを取得](https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-list-jobs.html)するには、「*AWS CLI コマンドリファレンス*」の「[ジョブのリスト取得](https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-list-jobs.html)」または「[list-jobs](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3control/list-jobs.html)」を参照してください。

### REST API の使用
<a name="Compute-checksum-api"></a>

[CreateJob](https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_CreateJob.html) を使用して、**[チェックサムを計算]** でオブジェクトの整合性を検証する REST リクエストを送信できます。REST リクエストを [DescribeJob](https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_DescribeJob.html) API オペレーションに送信することで、**[チェックサムを計算]** リクエストの進行状況をモニタリングできます。各バッチオペレーションジョブは、次のステータスで進行します。
+ **新規**
+ **準備中**
+ **準備完了**
+ **アクティブ**
+ **一時停止中**
+ **一時停止**
+ **完了**
+ **キャンセル中**
+ **[FAILED**]

API レスポンスは、現在のジョブ状態を通知します。