提问人:ericOnline 提问时间:10/19/2023 最后编辑:ericOnline 更新时间:10/20/2023 访问量:37
boto3 Python SDK “boto3.complete_multipart_upload()” 会计算每个部分的 SHA1 吗?
Does boto3 Python SDK "boto3.complete_multipart_upload()" calculate the SHA1 for each part?
问:
对我来说,文档不清楚。
如果您为分段对象启用了其他校验和值,则 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
答:
响应中的 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 执行的检查有点偏执,但没有法律禁止您下载刚刚上传的内容并再次验证它。
评论
--debug