boto3 Python SDK “boto3.complete_multipart_upload()” 会计算每个部分的 SHA1 吗?

Does boto3 Python SDK "boto3.complete_multipart_upload()" calculate the SHA1 for each part?

提问人:ericOnline 提问时间:10/19/2023 最后编辑:ericOnline 更新时间:10/20/2023 访问量:37

问:

对我来说,文档不清楚。

如果您为分段对象启用了其他校验和值,则 Amazon S3 会计算 使用指定的校验和算法对每个单独的部分进行校验和。 已完成对象的校验和的计算方式与 Amazon S3 计算分段上传的 MD5 摘要的方式相同。 您可以使用此校验和来验证对象的完整性。

当我将计算出的 SHA1 作为参数传递给该方法时,在此方法的响应中,我收到一个 SHA1 返回。upload_part()

响应中的 SHA1 是否实际由 AWS 计算?如果是这样,当它与我计算并发送到 AWS 的 SHA1 不匹配时会发生什么情况?

使用 multipart_upload 上传数据的函数

def upload_chunk_to_s3(s3_client, chunk, chunk_sha1, bucket, key, part_number, upload_id):
    resp = s3_client.upload_part(
        Bucket=bucket,
        Key=key,
        PartNumber=part_number,
        UploadId=upload_id,
        Body=chunk,
        ChecksumAlgorithm='SHA1',
        ChecksumSHA1=chunk_sha1  #<--this is calculated by me
    )
    return {'PartNumber': part_number, 'ETag': resp['ETag'], 'ChecksumSHA1': resp['ChecksumSHA1']}

来自 AWS 的响应

{
  "ResponseMetadata": {
    "RequestId": "<redact>",
    "HostId": "<redact>",
    "HTTPStatusCode": 200,
    "HTTPHeaders": {
      "x-amz-id-2": "<redact>",
      "x-amz-request-id": "<redact>",
      "date": "Wed, 18 Oct 2023 20:39:50 GMT",
      "etag": ""<redact>"",
      "x-amz-checksum-sha1": "<redact>b+KCk=",
      "x-amz-server-side-encryption": "AES256",
      "server": "AmazonS3",
      "content-length": "0"
    },
    "RetryAttempts": 0
  },
  "ServerSideEncryption": "AES256",
  "ETag": ""<md5_here>"",
  "ChecksumSHA1": "<redact>b+KCk=" #<-- calculated by AWS for each part of the multipart_upload?
}

编辑1

@Quassnoi - 谢谢你的见解,不过,在这些方面对我来说仍然模糊不清:

1.) 我正在使用 500 MiB 块。我的理解是,对于任何大于 16 MB 的块,Etag != MD5。那么,这是否意味着我计算的 SHA1 并将其应用于 AWS 返回的 != SHA1 的每个块?multipart_upload()multipart_upload()

2.) 作为multipart_upload的一部分,我需要验证整个文件的完整性。查询听起来像是返回我随每个块一起上传的 SHA1!GetObjectProperties

如果使用 GetObjectProperties 查询对象,它将返回 Checksum 对象,其中字段 ChecksumSHA1 填充如下: 对象的 base64 编码的 160 位 SHA-1 摘要。仅当它与对象一起上传时才会出现(这是否意味着它返回 MY SHA1 而不是 AWS 计算的 SHA1?对于分段上传,这可能不是对象的校验和值。(那么,如何在上传过程中将我计算的区块SHA1与AWS计算的SHA进行比较?有关如何通过分段上传计算校验和的更多信息,请参阅 Amazon S3 用户指南 中的检查对象完整性。(本文档引出更多问题。

在multipart_uploads期间查看检查文件完整性的示例会很有帮助。你知道任何例子吗?我一直找不到。boto3

亚马逊网络服务 boto3 sha1

评论

1赞 Quassnoi 10/19/2023
顺便说一句,您可以从 CLI 运行分段上传,并作为参数提供。它将显示在您的计算机和 AWS 之间传递的完整请求和响应。CLI 也是基于 boto3 构建的。--debug

答:

1赞 Quassnoi 10/19/2023 #1

响应中的 SHA1 是否实际由 AWS 计算?

是的,它是由 AWS 计算的。

如果是这样,当它与我计算并发送到 AWS 的 SHA1 不匹配时会发生什么情况?

S3 将拒绝上传并返回错误状态。


对我来说,文档不清楚。

这是您引用的摘录中的一行:

已完成对象的校验和的计算方式与 Amazon S3 计算分段上传的 MD5 摘要的方式相同。

,指的是文档的这一部分:

当对象作为分段上传上传时,对象的 ETag 不是整个对象的 MD5 摘要。Amazon S3 在上传每个单独的部分时计算该部分的 MD5 摘要。MD5 摘要用于确定最终对象的 ETag。Amazon S3 将 MD5 摘要的字节连接在一起,然后计算这些串联值的 MD5 摘要。创建 ETag 的最后一步是 Amazon S3 在末尾添加一个短划线,其中包含部分总数。

如果使用 GetObjectAttributes 查询对象,它将返回 Checksum 对象,其中字段填充如下:ChecksumSHA1

对象的 base64 编码的 160 位 SHA-1 摘要。仅当它与对象一起上传时,才会显示此消息。对于分段上传,这可能不是对象的校验和值。有关如何通过分段上传计算校验和的更多信息,请参阅 Amazon S3 用户指南 中的检查对象完整性。

要验证对象作为一个整体的完整性,您需要知道它被上传为的所有部分的哈希值。

这也意味着,如果将对象作为一个整体复制到另一个位置(而不是使用多部分复制),则其摘要将更改。

这是否意味着它返回的是 MY SHA1 而不是 AWS 计算的 SHA1?

这不是一个有意义的区别。如果您的 SHA1 与 S3 计算的结果不匹配,则上传将被拒绝,并且不会返回任何内容。如果它返回了一些东西(基本上是出于礼貌),它与您在标头中提供的内容相匹配。

那么,如何在上传过程中将我计算的区块 SHA1 与 AWS 计算的 SHA 进行比较呢?

要验证整个对象,您需要知道其所有部分的校验和。计算公式如下:

ChecksumSHA1(object) = SHA1(SHA1(parts[0]) || SHA1(parts[1]) || … || SHA1(parts[n])) || '-' || parts.length

部件的各个校验和也可在 的输出中找到。GetObjectAttributes

当您想要验证驱动器上的内容(包括所有坏块和宇宙射线位翻转)是否与 AWS 在对象元数据中的内容匹配时,校验和流程更适合下载。

在初始上传期间仔细检查是否通过了 S3 执行的检查有点偏执,但没有法律禁止您下载刚刚上传的内容并再次验证它。

评论

0赞 ericOnline 10/19/2023
谢谢@Quassnoi。请参阅上面的编辑 1
0赞 ericOnline 10/20/2023
棒。感谢您的空闲和参与。这对我帮助很大。我的问题(我实现 SHA1 的原因)最终是一个 off-by-1 错误。SHA 与每个区块匹配,但尝试在 AWS 端打开文件时文件已损坏。我的分块逻辑偏离了 1 个字节。