View a markdown version of this page

使用校验和实现数据完整性保护 - 适用于 Kotlin 的 AWS SDK

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用校验和实现数据完整性保护

Amazon Simple Storage Service (Amazon S3) 允许您在上传对象时指定校验和。当您指定校验和时,校验和与对象一起存储,并且可以在下载对象时验证该校验和。

传输文件时,校验和可提供额外的数据层完整性。使用校验和,您可以通过确认收到文件与原始文件是否匹配来验证数据一致性。有关 Amazon S3 校验和的更多信息,请参阅 Amazon Simple Storage Service 用户指南,包括支持的算法

您可以灵活地选择最适合自己需求的算法,并让 SDK 计算校验和。或者,您也可以使用任一受支持的算法,提供预先计算好的校验和值。

注意

从的 1.4.0 版开始 适用于 Kotlin 的 AWS SDK,SDK 通过自动计算上传的CRC32校验和来提供默认的完整性保护。如果您未提供预先计算的校验和值,或者没有指定 SDK 计算校验和时应使用的算法,SDK 就会计算此校验和。

该 SDK 还提供了可在外部设置的数据完整性保护全局设置,您可以在 AWS SDK 和工具参考指南中查阅相关说明。

我们在两个请求阶段讨论校验和:上传对象和下载对象。

上传对象

您可以使用带请求参数的 putObject 函数,通过适用于 Kotlin 的 SDK 将对象上传到 Amazon S3。请求数据类型提供用于启用校验和计算的 checksumAlgorithm 属性。

以下代码段展示了上传具有 CRC32 校验和的对象的请求。当 SDK 发送请求时,它会计算 CRC32 校验和并上传对象。Amazon S3 将校验和与对象一起存储。

val request = PutObjectRequest { bucket = "amzn-s3-demo-bucket" key = "key" checksumAlgorithm = ChecksumAlgorithm.CRC32 }

如果您未在请求中提供校验和算法,则校验和行为将根据您使用的 SDK 版本而异,具体如下表所示。

未提供校验和算法时的校验和行为

Kotlin SDK 版本 校验和行为
1.4.0 之前的版本 SDK 不会自动计算 CRC-based 校验和并在请求中提供校验和。
1.4.0 或更高版本

SDK 使用 CRC32 算法计算校验和,并在请求中提供该值。Amazon S3 通过计算自己的 CRC32 校验和并将其与 SDK 提供的校验和进行对比,从而验证传输的完整性。如果校验和匹配,则校验和将与对象一起保存。

使用预先计算的校验和值

与请求一起提供的预先计算校验和值会禁用 SDK 的自动计算,而是使用提供的值。

以下示例显示了具有预先计算的 SHA256 校验和的请求。

val request = PutObjectRequest { bucket = "amzn-s3-demo-bucket" key = "key" body = ByteStream.fromFile(File("file_to_upload.txt")) checksumAlgorithm = ChecksumAlgorithm.SHA256 checksumSha256 = "cfb6d06da6e6f51c22ae3e549e33959dbb754db75a93665b8b579605464ce299" }

如果 Amazon S3 确定指定算法的校验和值不正确,服务就会返回错误响应。

分段上传

您也可以将校验和用于分段上传。

您必须在 CreateMultipartUpload 请求和每个 UploadPart 请求中指定校验和算法。最后一步,您必须在 CompleteMultipartUpload 中指定每个分段的校验和。以下示例展示了如何创建具有指定校验和算法的分段上传。

val multipartUpload = s3.createMultipartUpload { bucket = "amzn-s3-demo-bucket" key = "key" checksumAlgorithm = ChecksumAlgorithm.Sha1 } val partFilesToUpload = listOf("data-part1.csv", "data-part2.csv", "data-part3.csv") val completedParts = partFilesToUpload .mapIndexed { i, fileName -> val uploadPartResponse = s3.uploadPart { bucket = "amzn-s3-demo-bucket" key = "key" body = ByteStream.fromFile(File(fileName)) uploadId = multipartUpload.uploadId partNumber = i + 1 // Part numbers begin at 1. checksumAlgorithm = ChecksumAlgorithm.Sha1 } CompletedPart { eTag = uploadPartResponse.eTag partNumber = i + 1 checksumSha1 = uploadPartResponse.checksumSha1 } } s3.completeMultipartUpload { uploadId = multipartUpload.uploadId bucket = "amzn-s3-demo-bucket" key = "key" multipartUpload { parts = completedParts } }

下载对象

使用 getObject 方法下载对象时,在以下情况下 SDK 会自动验证校验和:如果适用于 GetObjectRequest 的生成器的 checksumMode 属性设置为 ChecksumMode.Enabled

以下代码段中的请求引导 SDK 通过计算校验和并比较值来验证响应中的校验和。

val request = GetObjectRequest { bucket = "amzn-s3-demo-bucket" key = "key" checksumMode = ChecksumMode.Enabled }
注意

如果上传对象时没有使用校验和,则不会进行验证。

如果您使用的是 1.4.0 或更高版本的 SDK,SDK 会自动检查 getObject 请求的完整性,而无需将 checksumMode = ChecksumMode.Enabled 添加到请求中。

异步验证

由于适用于 Kotlin 的 SDK 在从 Amazon S3 下载对象时使用流式响应,因此将在您使用该对象时计算校验和。因此,您必须使用该对象才能验证校验和。

以下示例展示了如何通过充分使用响应来验证校验和。

val request = GetObjectRequest { bucket = "amzn-s3-demo-bucket" key = "key" checksumMode = checksumMode.Enabled } val response = s3Client.getObject(request) { println(response.body?.decodeToString()) // Fully consume the object. // The checksum is valid. }

相比之下,以下示例中的代码并未以任何方式使用该对象,因此不会验证校验和。

s3Client.getObject(request) { println("Got the object.") }

如果由 SDK 计算的校验和与随响应一起发送的预期校验和不匹配,SDK 就会抛出 ChecksumMismatchException