ablog

不器用で落着きのない技術者のメモ

AWS SDK はファイルを S3 にアップロードする際にチェックサムで整合性をチェックしてくれる

AWS SDKMD5 以外を使うと自動でチェックサムをチェックしてくれると聞いて試してみた。

新しいチェックサムのサポート
2022 年 2 月 25 日(米国時間)は、S3 の 4 つのチェックサムアルゴリズムの新しいサポートについてお話しします。Amazon S3 に保存されているデータのチェックサムを計算して保存し、そのチェックサムを使用してアップロードおよびダウンロードリクエストの整合性を確認することが非常に簡単になりました。
(中略)
オブジェクトアップロードAWS SDK の最新バージョンでは、指定されたチェックサムがアップロードの一部として計算され、アップロードの終了時に HTTP トレーラーに含められます。また、事前計算済みチェックサムを指定するオプションもあります。いずれの場合も、S3 はチェックサムを検証し、リクエストの値が S3 によって計算された値と一致する場合はオペレーションを受け入れます。

新機能 – Amazon S3 向け、追加のチェックサムアルゴリズム | Amazon Web Services ブログ

手順

  • アップロードするファイル
$ cat test.txt 
test
$ python s3api put-object --bucket test-bucket-az --key test.txt --body /home/ec2-user/test.txt --checksum-algorithm SHA256
{
    "ETag": "\"d8e8fca2dc0f896fd7cb4cb0031ba249\"",
    "ChecksumSHA256": "8sobtsfpB9Btr+Roflefznazfk6Tt2BQItpS5szCb9I=",
    "ServerSideEncryption": "AES256"
}
$ aws s3api get-object-attributes --bucket test-bucket-az --key test.txt --object-attributes Checksum
{
    "LastModified": "2023-11-28T11:17:33+00:00",
    "Checksum": {
        "ChecksumSHA256": "8sobtsfpB9Btr+Roflefznazfk6Tt2BQItpS5szCb9I="
    }
}

デバッグログ

  • 実行する
$ aws s3api put-object --debug --bucket test-bucket-az --key test.txt --body /home/ec2-user/test.txt --checksum-algorithm SHA256 > debug.log 2>&1
  • debug.log
2023-11-29 00:59:11,123 - MainThread - awscli.clidriver - DEBUG - CLI version: aws-cli/2.9.19 Python/3.9.16 Linux/6.1.61-85.141.amzn2023.x86_64 source/x86_64.amzn.2023
2023-11-29 00:59:11,124 - MainThread - awscli.clidriver - DEBUG - Arguments entered to CLI: ['s3api', 'put-object', '--debug', '--bucket', 'appflow-sfdc-test', '--key', 'test.txt', '--body', '/home/ec2-user/test.txt', '--checksum-algorithm', 'SHA256']

...

2023-11-29 00:59:11,217 - MainThread - botocore.hooks - DEBUG - Event before-call.s3.PutObject: calling handler <function inject_api_version_header_if_needed at 0x7f483bc041f0>
2023-11-29 00:59:11,217 - MainThread - botocore.endpoint - DEBUG - Making request for OperationModel(name=PutObject) with params: {'url_path': '/test.txt', 'query_string': {}, 'method': 'PUT', 'headers': {'x-amz-sdk-checksum-algorithm': 'SHA256', 'User-Agent': 'aws-cli/2.9.19 Python/3.9.16 Linux/6.1.61-85.141.amzn2023.x86_64 source/x86_64.amzn.2023 prompt/off command/s3api.put-object', 'Expect': '100-continue', 'Transfer-Encoding': 'chunked', 'Content-Encoding': 'aws-chunked', 'X-Amz-Trailer': 'x-amz-checksum-sha256', 'X-Amz-Decoded-Content-Length': '5'}, 'body': <botocore.httpchecksum.AwsChunkedWrapper object at 0x7f4839070fd0>, 'auth_path': '/test-bucket-az/test.txt', 'url': 'https://test-bucket-az.s3.ap-northeast-1.amazonaws.com/test.txt', 'context': {'client_region': 'ap-northeast-1', 'client_config': <botocore.config.Config object at 0x7f4839100e50>, 'has_streaming_input': True, 'auth_type': 'v4', 'signing': {'region': 'ap-northeast-1', 'signing_name': 's3', 'disableDoubleEncoding': True}, 's3_redirect': {'redirected': False, 'bucket': 'test-bucket-az', 'params': {'Body': <_io.BufferedReader name='/home/ec2-user/test.txt'>, 'Bucket': 'test-bucket-az', 'ChecksumAlgorithm': 'SHA256', 'Key': 'test.txt'}}, 'checksum': {'request_algorithm': {'algorithm': 'sha256', 'in': 'trailer', 'name': 'x-amz-checksum-sha256'}}}}
2023-11-29 00:59:11,217 - MainThread - botocore.hooks - DEBUG - Event request-created.s3.PutObject: calling handler <bound method RequestSigner.handler of <botocore.signers.RequestSigner object at 0x7f4839100ee0>>
2023-11-29 00:59:11,217 - MainThread - botocore.hooks - DEBUG - Event choose-signer.s3.PutObject: calling handler <function set_operation_specific_signer at 0x7f483bc8e820>
2023-11-29 00:59:11,217 - MainThread - botocore.hooks - DEBUG - Event before-sign.s3.PutObject: calling handler <function remove_arn_from_signing_path at 0x7f483bc049d0>
2023-11-29 00:59:11,217 - MainThread - botocore.auth - DEBUG - Calculating signature using v4 auth.
2023-11-29 00:59:11,217 - MainThread - botocore.auth - DEBUG - CanonicalRequest:
PUT
/test.txt

content-encoding:aws-chunked
host:test-bucket-az.s3.ap-northeast-1.amazonaws.com
transfer-encoding:chunked
x-amz-content-sha256:STREAMING-UNSIGNED-PAYLOAD-TRAILER
x-amz-date:20231129T005911Z
x-amz-decoded-content-length:5
x-amz-sdk-checksum-algorithm:SHA256
x-amz-security-token:IQoJb3 ... FJNbSZQ==
x-amz-trailer:x-amz-checksum-sha256

content-encoding;host;transfer-encoding;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-sdk-checksum-algorithm;x-amz-security-token;x-amz-trailer
STREAMING-UNSIGNED-PAYLOAD-TRAILER
2023-11-29 00:59:11,218 - MainThread - botocore.auth - DEBUG - StringToSign:
AWS4-HMAC-SHA256
20231129T005911Z
20231129/ap-northeast-1/s3/aws4_request
b12 ... 931
2023-11-29 00:59:11,218 - MainThread - botocore.auth - DEBUG - Signature:
da3 ... 941
2023-11-29 00:59:11,218 - MainThread - botocore.endpoint - DEBUG - Sending http request: <AWSPreparedRequest stream_output=False, method=PUT, url=https://test-bucket-az.s3.ap-northeast-1.amazonaws.com/test.txt, headers={'x-amz-sdk-checksum-algorithm': b'SHA256', 'User-Agent': b'aws-cli/2.9.19 Python/3.9.16 Linux/6.1.61-85.141.amzn2023.x86_64 source/x86_64.amzn.2023 prompt/off command/s3api.put-object', 'Expect': b'100-continue', 'Transfer-Encoding': b'chunked', 'Content-Encoding': b'aws-chunked', 'X-Amz-Trailer': b'x-amz-checksum-sha256', 'X-Amz-Decoded-Content-Length': b'5', 'X-Amz-Date': b'20231129T005911Z', 'X-Amz-Security-Token': b'IQoJb3 ... FJNbSZQ==', 'X-Amz-Content-SHA256': b'STREAMING-UNSIGNED-PAYLOAD-TRAILER', 'Authorization': b'AWS4-HMAC-SHA256 Credential=ASI ... L7S/20231129/ap-northeast-1/s3/aws4_request, SignedHeaders=content-encoding;host;transfer-encoding;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-sdk-checksum-algorithm;x-amz-security-token;x-amz-trailer, Signature=da ... 941'}>
2023-11-29 00:59:11,218 - MainThread - botocore.httpsession - DEBUG - Certificate path: /usr/lib/python3.9/site-packages/awscli/botocore/cacert.pem
2023-11-29 00:59:11,218 - MainThread - urllib3.connectionpool - DEBUG - Starting new HTTPS connection (1): test-bucket-az.s3.ap-northeast-1.amazonaws.com:443
2023-11-29 00:59:11,326 - MainThread - urllib3.connectionpool - DEBUG - https://test-bucket-az.s3.ap-northeast-1.amazonaws.com:443 "PUT /test.txt HTTP/1.1" 200 0
2023-11-29 00:59:11,326 - MainThread - botocore.parsers - DEBUG - Response headers: {'x-amz-id-2': 'hsM2C/ ... 9w88=', 'x-amz-request-id': '92DYK4N49D9MG071', 'Date': 'Wed, 29 Nov 2023 00:59:12 GMT', 'x-amz-server-side-encryption': 'AES256', 'ETag': '"d8e8fca2dc0f896fd7cb4cb0031ba249"', ★'x-amz-checksum-sha256': '8sobtsfpB9Btr+Roflefznazfk6Tt2BQItpS5szCb9I=', 'Server': 'AmazonS3', 'Content-Length': '0', 'Connection': 'close'}
2023-11-29 00:59:11,327 - MainThread - botocore.parsers - DEBUG - Response body:
b''
2023-11-29 00:59:11,327 - MainThread - botocore.hooks - DEBUG - Event needs-retry.s3.PutObject: calling handler <bound method RetryHandler.needs_retry of <botocore.retries.standard.RetryHandler object at 0x7f48390707c0>>
2023-11-29 00:59:11,327 - MainThread - botocore.retries.standard - DEBUG - Not retrying request.
2023-11-29 00:59:11,327 - MainThread - botocore.hooks - DEBUG - Event needs-retry.s3.PutObject: calling handler <bound method S3RegionRedirectorv2.redirect_from_error of <botocore.utils.S3RegionRedirectorv2 object at 0x7f4839070850>>
2023-11-29 00:59:11,327 - MainThread - botocore.hooks - DEBUG - Event after-call.s3.PutObject: calling handler <function enhance_error_msg at 0x7f483a56e9d0>
2023-11-29 00:59:11,327 - MainThread - botocore.hooks - DEBUG - Event after-call.s3.PutObject: calling handler <bound method RetryQuotaChecker.release_retry_quota of <botocore.retries.standard.RetryQuotaChecker object at 0x7f4839070310>>
2023-11-29 00:59:11,327 - MainThread - awscli.formatter - DEBUG - RequestId: 92DYK4N49D9MG071
{
    "ETag": "\"d8e8fca2dc0f896fd7cb4cb0031ba249\"",
    "ChecksumSHA256": "8sobtsfpB9Btr+Roflefznazfk6Tt2BQItpS5szCb9I=", ★
    "ServerSideEncryption": "AES256"
}

参考

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

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

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

スケーラブルなチェックサムの構築 | Amazon Web Services ブログ
1.21.7
======

* api-change:``s3``: [``botocore``] This release adds support for new integrity checking capabilities in Amazon S3. You can choose from four supported checksum algorithms for data integrity checking on your upload and download requests. In addition, AWS SDK can automatically calculate a checksum as it streams data into S3
boto3/CHANGELOG.rst at develop · boto/boto3 · GitHub

x-amz-sdk-checksum-algorithm
Indicates the algorithm used to create the checksum for the object when using the SDK. This header will not provide any additional functionality if not using the SDK. When sending this header, there must be a corresponding x-amz-checksum or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the HTTP status code 400 Bad Request. For more information, see Checking object integrity in the Amazon S3 User Guide.

If you provide an individual checksum, Amazon S3 ignores any provided ChecksumAlgorithm parameter.

Valid Values: CRC32 | CRC32C | SHA1 | SHA256
PutObject - Amazon Simple Storage Service