オブジェクトの整合性をチェックする - Amazon Simple Storage Service

オブジェクトの整合性をチェックする

Amazon S3 は、チェックサム値を使用して、Amazon S3 にアップロードまたはダウンロードするデータの整合性を検証します。さらに、Amazon S3 に保存するオブジェクトについて、別のチェックサム値を計算するようにリクエストすることもできます。データをアップロードまたはコピーするときに使用するチェックサムアルゴリズムのいずれかを選択できます。Amazon S3 は、このアルゴリズムを使用して追加のチェックサム値を計算し、オブジェクトメタデータの一部として保存します。

オブジェクトをアップロードするときに、オプションで事前計算されたチェックサムをリクエストの一部として含めることができます。Amazon S3 は、指定されたアルゴリズムを使用して計算したチェックサムと、指定されたチェックサムを比較します。2 つの値が一致しない場合、Amazon S3 はエラーを報告します。

サポートされているチェックサムアルゴリズムの使用

Amazon S3 では、アップロードまたはダウンロード中にデータを検証するために使用されるチェックサムアルゴリズムを選択するオプションがあります。次のセキュアハッシュアルゴリズム (SHA) または巡回冗長検査 (CRC) のデータ整合性チェックアルゴリズムのいずれかを選択できます。

  • CRC32

  • CRC32C

  • SHA-1

  • SHA-256

オブジェクトをアップロードするときに、使用するアルゴリズムを指定できます。

  • AWS Management Console を使用するときには、使用するチェックサムのアルゴリズムを選択します。その場合、オプションでオブジェクトのチェックサム値を指定できます。Amazon S3 は、オブジェクトを受信すると、指定したアルゴリズムを使用してチェックサムを計算します。2 つの値が一致しない場合、Amazon S3 はエラーを生成します。

  • SDK を使用しているときにはx-amz-sdk-checksum-algorithm パラメータの値を、Amazon S3 がチェックサムの計算時に 使用するアルゴリズムに設定できます。Amazon S3 はチェックサム値を自動的に計算します。

  • REST API を使用しているときにはx-amz-sdk-checksum-algorithm パラメータを使用しません。代わりに、アルゴリズム固有のヘッダーのいずれかを使用します (例えば、x-amz-checksum-crc32)。

オブジェクトのアップロードの詳細については、「オブジェクトのアップロード」を参照してください。

Amazon S3 にすでにアップロードされているオブジェクトにこれらのチェックサム値を適用するには、オブジェクトをコピーします。オブジェクトをコピーするとき、既存のチェックサムアルゴリズムを使用するか、新しいチェックサムアルゴリズムを使用するかを指定できます。S3 バッチ操作など、サポートされているオブジェクトのコピーメカニズムを使用するときには、チェックサムアルゴリズムを指定できます。S3 バッチ操作について詳しくは、Amazon S3 オブジェクトでの大規模なバッチ操作の実行 を参照してください。

重要

追加のチェックサムを含むマルチパートアップロードを使用する場合、マルチパート番号には連続するパート番号を使用する必要があります。追加のチェックサムを使用するとき、連続しないパート番号でマルチパートアップロードリクエストを完了しようとすると、Amazon S3 は HTTP 500 Internal Server Error エラーを生成します。

オブジェクトをアップロードした後、チェックサム値を取得し、同じアルゴリズムを使用して計算された事前計算済みまたは以前に保存されたチェックサム値と比較できます。

コンソールの使用方法およびオブジェクトのアップロード時に使用するチェックサムアルゴリズムの指定の詳細については、「オブジェクトのアップロード」を参照してください。

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

Java

例: SHA-256 を使用して大きなファイルをアップロード、ダウンロード、および検証する

ワーキングサンプルの作成とテストに関する手順については、Amazon S3 Java コード例のテスト を参照してください。

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 リクエストを送信して、チェックサムの値を持つオブジェクトをアップロードし、PutObject でデータの整合性を検証できます。GetObject または HeadObject を使用して、オブジェクトのチェックサムの値を取得することもできます。

単一のオペレーションで、最大 5 GB のオブジェクトをアップロードする PUT リクエストを送信できます。詳細については、「AWS CLI コマンドリファレンス」の PutObject を参照してください。また、get-objecthead-object を使用して、すでにアップロードされたオブジェクトのチェックサムを取得し、データの整合性を検証することもできます。

オブジェクトをアップロードするときに Content-MD5 を使用する

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

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

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

Content-MD5 と ETag を使用して、アップロードされたオブジェクトを検証する

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

オブジェクトによっては、オブジェクトの ETag がオブジェクトデータの MD5 ダイジェストである場合があります。

  • オブジェクトが PUT ObjectPOST Object、または Copy オペレーションによって、または AWS Management Console を介して作成され、そのオブジェクトがプレーンテキストか、Amazon S3 マネージドキーを使用したサーバー側の暗号化 (SSE-S3) によって暗号化されている場合、そのオブジェクトの ETag は、オブジェクトデータの MD5 ダイジェストです。

  • オブジェクトが PUT ObjectPOST Object、または Copy オペレーションによって、または AWS Management Console を介して作成され、そのオブジェクトがお客様が用意したキーを使用したサーバー側の暗号化 (SSE-C) または AWS Key Management Service (AWS KMS) キーを使用したサーバー側の暗号化 (SSE-KMS) によって暗号化されている場合、そのオブジェクトの ETag は、オブジェクトデータの MD5 ダイジェストではありません。

  • オブジェクトが Multipart Upload または Part Copy オペレーションによって作成された場合、暗号化の方法に関係なく、オブジェクトの ETag は MD5 ダイジェストではありません。オブジェクトが 16 MB より大きい場合、AWS Management Console はそのオブジェクトをマルチパートアップロードとしてアップロードまたはコピーするため、ETag は MD5 ダイジェストではありません。

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

追跡チェックサムの使用

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 を使用したオブジェクトの変換」を参照してください。

マルチパートアップロードにパートレベルのチェックサムを使用する

オブジェクトが Amazon S3 にアップロードされるときには、単一のオブジェクトとしてアップロードされるか、マルチパートアップロードプロセスを通じてアップロードされます。16 MB を超え、コンソールからアップロードされるオブジェクトは、マルチパートアップロードを使用して自動的にアップロードされます。マルチパートアップロードの詳細については、「マルチパートアップロードを使用したオブジェクトのアップロードとコピー」を参照してください。

オブジェクトがマルチパートアップロードとしてアップロードされるとき、オブジェクトの ETag はオブジェクト全体の MD5 ダイジェストではありません。Amazon S3 は、アップロードされた個々のパートの MD5 ダイジェストを計算します。MD5 ダイジェストは、最終的なオブジェクトの ETag を決定するために使用されます。Amazon S3 は MD5 ダイジェストのバイトを連結し、これらの連結値の MD5 ダイジェストを計算します。ETag を作成するための最後のステップは、Amazon S3 がパートの総数を含むダッシュを最後に追加するときです。

例えば、ETag が C9A5A6878D97B48CC965C1E41859F034-14 のマルチパートアップロードでアップロードされたオブジェクトを考えてみましょう。この場合、C9A5A6878D97B48CC965C1E41859F034 は、連結されたすべてのダイジェストの MD5 ダイジェストです。-14 は、このオブジェクトのマルチパートアップロードに 14 個のパートが関連付けられていることを示します。

マルチパートオブジェクトに対して追加のチェックサム値を有効にした場合、Amazon S3 は、指定されたチェックサムアルゴリズムを使用して、個々のパートのチェックサムを計算します。完了したオブジェクトのチェックサムは、Amazon S3 がマルチパートアップロードの MD5 ダイジェストを計算するのと同じ方法で計算されます。このチェックサムを使用して、オブジェクトの整合性を検証できます。

オブジェクト全体を構成するパートの数など、オブジェクトに関する情報を取得するには、GetObjectAttributes オペレーションを使用します。追加のチェックサムを使用すると、各パートのチェックサム値を含む個々のパートの情報を回復することもできます。

または、GetObject または HeadObject オペレーションを使用し、1 つのパートのパート番号またはバイト範囲を指定することによって、個々のパートのチェックサムを取得することもできます。この方法では、そのチェックサムを使用して個々のパートを検証でき、データの整合性を検証するのに、すべてのパートのアップロードが完了するのを待つ必要はありません。この方法を使用すると、整合性テストに失敗した個々のパートのみをリクエストすることもできます。

Amazon S3 はマルチパートオブジェクトのチェックサムを計算するので、オブジェクトをコピーした場合、チェックサム値が変更されることがあります。SDK または REST API を使用しており、CopyObject を呼び出した場合、Amazon S3 は CopyObject API オペレーションのサイズ制限までオブジェクトをコピーします。Amazon S3 は、オブジェクトが単一のリクエストでアップロードされたか、マルチパートアップロードの一部としてアップロードされたかにかかわらず、このコピーを単一のアクションとして実行します。copy コマンドでは、オブジェクトのチェックサムは、完全なオブジェクトの直接チェックサムです。オブジェクトが最初にマルチパートアップロードを使用してアップロードされた場合、データにはない場合でも、チェックサム値が変更されます。

注記

CopyObject API オペレーションのサイズ制限よりも大きいオブジェクトは、マルチパート copy コマンドを使用する必要があります。

重要

AWS Management Console を使用していくつかの操作を実行するとき、オブジェクトのサイズが 16 MB より大きい場合、Amazon S3 はマルチパートアップロードを使用します。この場合、チェックサムは完全なオブジェクトの直接チェックサムではなく、個々のパートのチェックサム値に基づく計算です。

例えば、REST API を使用してシングルパートダイレクトアップロードとしてアップロードした 100 MB のサイズのオブジェクトがあるとします。この場合のチェックサムは、オブジェクト全体のチェックサムです。後でコンソールを使用してオブジェクトの名前変更、コピー、ストレージクラスの変更、またはメタデータの編集を行った場合、Amazon S3 はマルチパートアップロード機能を使用してオブジェクトを更新します。その結果、Amazon S3 は、個々のパートのチェックサム値に基づいて計算されるオブジェクトの新しいチェックサム値を作成します。

前述のコンソール操作のリストは、AWS Management Console で実行できるすべてのアクションの完全なリストではなく、その結果、Amazon S3 はマルチパートアップロード機能を使用してオブジェクトを更新します。コンソールを使用してサイズが 16 MB を超えるオブジェクトを操作する場合、チェックサム値はオブジェクト全体のチェックサムではない場合があることに注意してください。