近期在处理OTA升级包数据完整性这个问题 引发了一系列的review。如何保证服务器上传到S3 S3收到的升级文件是完整的,如何保证设备获取到的升级文件是完整。这里其实就涉及到两个问题:
1 在上传文件到S3如何确定上传过程数据不被损坏
2 如何把保证下载过程数据如何不被损坏
这里S3果然有进行考虑:https://aws.amazon.com/cn/premiumsupport/knowledge-center/data-integrity-s3/
1 关于S3 ETag
实体标签(ETag)代表一个对象特殊的版本。ETag只反映对象内容的变化并不是对象的metadata(元数据)。ETag可能是也可能不是对象数据的md5值。这取决于对象是如何被创建和加密的。如下所述:
- 通过AWS管理控制台或通过PUT对象、POST对象或复制操作创建的对象:
- 对象通过SSE-S3加密或明文加密的对象具有ETags, ETags是其数据的MD5摘要。
- 对象被SSE-C或SSE-KMS加密的对象,其ETags不是对象数据的MD5摘要。
- 由Multipart Upload或Part Copy操作创建的对象的ETags不是MD5摘要,无论加密的方法。
2 上传完整性校验
为确保通过网络的数据不会损坏,请使用 Content-MD5标头。当您使用此标头时,Amazon S3 会根据提供的 MD5 值检查对象,如果不匹配,则返回错误。此外,您可以在将对象放入 Amazon S3 时计算 MD5,并将返回的 ETag 与计算的 MD5 值进行比较。
方式1:
您使用 Content-MD5 标头时,Amazon S3 会根据提供的 Content-MD5 值检查对象。如果值不匹配,则会收到错误消息。
- 计算对象的 Content-MD5 值。
- 通过在对象上载期间将 Content-MD5 值作为请求标头传递来验证上载对象的完整性。
方式2:
上传对象完成后,会返回ETag 和本地文件md5 的值进行对比 不一致则认为上传途中发生了异常。
这里提供nodejs 示例代码:
'use strict';
const AWSS3 = require('aws-sdk').S3;
const crypto = require('crypto');
const fs = require('fs');
const hashmd5 = crypto.createHash('md5');
const buffer = fs.readFileSync('cjlog.jpg'); // 读取测试图片
const base64 = hashmd5.update(buffer).digest('base64'); // md5运算并进行base64编码
const Bucket = ''; // 填写S3存储桶
const filePath = 'test.jpg'; // 测试文件在存储桶中位置
const s3 = new AWSS3({
region: 'cn-northwest-1', // S3 区域
accessKeyId: '', // AWS 凭证
secretAccessKey: '', // AWS 凭证
});
s3.putObject({
Bucket,
Key: filePath,
Body: buffer,
ContentMD5: base64,//The base64-encoded 128-bit MD5 digest of the message (without the headers) according to RFC 1864. This header can be used as a message integrity check to verify that the data is the same data that was originally sent. Although it is optional, we recommend using the Content-MD5 mechanism as an end-to-end integrity check. For more information about REST request authentication
}, (err, data) => {
if(err) console.error(err);
console.log(data);
s3.getSignedUrl('getObject', { Bucket, Key: filePath, Expires: 3600 },(err, url) => {
if(err) console.error(err);
console.log(url);
});
});
输出值:
{ ETag: '"b75687455273f7889bcea0bf6b2e4c22"' }
https://test.s3.cn-northwest-1.amazonaws.com.cn/test.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=HHHHHH%2F20220215%2Fcn-northwest-1%2Fs3%2Faws4_request&X-Amz-Date=20220215T061711Z&X-Amz-Expires=3600&X-Amz-Signature=56c44d5cfb3605b4db26969e2eee4afd2c3b42306ac53d32e281f270334e8a8d&X-Amz-SignedHeaders=host
输出内容为S3计算的文件Etag
和一个对该Object 进行了可下载签名后的url
3 下载完整性校验
使用1中下载连接下载图片,在http response 的header中携带ETag 属性
Accept-Ranges: bytes
Content-Length: 212284
Content-Type: application/octet-stream
Date: Tue, 15 Feb 2022 02:39:24 GMT
ETag: "b75687455273f7889bcea0bf6b2e4c22"
Last-Modified: Tue, 15 Feb 2022 02:39:16 GMT
Server: AmazonS3
对下载的得到的文件 进行md5 运算得到的md5值与ETag 进行对比,则说明文件一致 没有出现错误。