Azure 进阶攻略 | 文件完整性,你打算如何证明?_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > Azure 进阶攻略 | 文件完整性,你打算如何证明?

Azure 进阶攻略 | 文件完整性,你打算如何证明?

 2017/8/14 17:31:26  DavidZang  程序员俱乐部  我要评论(0)
  • 摘要:假设你是一位独立软件开发者,通过自己的网站提供软件下载。网站完全托管在Azure中,并且软件下载也是通过AzureBlob存储和AzureCDN服务提供的。这做法真不错,不需要自己管理服务器,就可以快速低成本地建立网站,并且用户数量再多也不担心网站撑不住了。一个风和日丽的下午,你搞定了新版软件开发,第一时间上传到Blob存储,等着用户们下载升级。然而很快便收到消息:下载的新版没法解压缩,接着越来越多用户反馈说遇到类似问题。后来检查发现,最初上传到Blob的过程中,因为某种莫名其妙的原因
  • 标签:文件 打算 攻略

假设你是一位独立软件开发者,通过自己的网站提供软件下载。网站完全托管在 Azure 中,并且软件下载也是通过 Azure Blob 存储和 Azure CDN 服务提供的。

这做法真不错,不需要自己管理服务器,就可以快速低成本地建立网站,并且用户数量再多也不担心网站撑不住了。

一个风和日丽的下午,你搞定了新版软件开发,第一时间上传到 Blob 存储,等着用户们下载升级。然而很快便收到消息:下载的新版没法解压缩,接着越来越多用户反馈说遇到类似问题。

后来检查发现,最初上传到 Blob 的过程中,因为某种莫名其妙的原因,上传的文件本身就是损坏的……

 

So,你下载上传的文件

「真正」就是你需要的那个文件吗?

我们可以通过文件校验值的方式来解决这种问题:通过专用工具,用不同计算方法(例如 MD5)对文件计算校验值,随后在需要时重新计算文件校验值,并与最初的值对比。如果因为任何原因(网络问题、磁盘故障、病毒篡改)导致文件中哪怕有一个比特的内容有了变化,都会导致校验值产生极大不同。而校验值不同,就意味着文件受损了!

因此为了避免上面提到的悲剧,你只需要:

1、在将文件上传到 Azure Blob 存储(或其他任何网络位置)前,在自己电脑上使用校验工具算出文件的校验值,并对上传后的文件重新计算比较校验值,确保上传过程没有导致文件损坏。

2、让用户下载你的文件同时,在网页上提供文件校验值。这样有需要的用户就可以在下载之后进行计算和比较,确保自己下载过程没有导致文件损坏。

很多小伙伴可能举手问我:怎样计算文件的校验值呢?此类工具非常多,微软也提供了一个免费的工具。该工具支持通过 MD5 和 SHA-1 两种计算方法计算文件的校验值。

那么,对于上传到 Azure Blob 中的文件,如何实现自动计算和对比校验值?难道每次都要自己重新下载进行对比么?太麻烦了啊!

 

Azure Blob

可以自动帮你计算和对比 MD5 哦!

在上传文件或者其他二进制内容到 Azure Blob 存储时,可以利用请求中的 MD5 值来验证内容完整性,而上传成功后的 Blob 属性里面也会包含 MD5 这个属性,以用作后续的验证。

首先需要注意,完整性检查是基于当前 REST 请求的,也就是说只会对当前上传内容进行 MD5 值的计算和对比,因为 REST API 是无状态的。

随后要注意,基于 MD5 的完整性检查,工作过程是这样的:

1.(在上传者本地)计算当前上传内容的 MD5 值,

2. 在当前上传文件的 REST 请求头部(Content-MD5)设置该 MD5 值,

3. 服务端根据当前请求里的内容计算 MD5,并对比请求头部中的 MD5 值,

4. 相同则验证成功,并将该 MD5 值赋予 Blob 的 MD5 属性,否则失败。

最后,上传到 Azure Blob 支持两种方式,整体上传和分块上传。可以采用整体上传方式,一个请求完成;如果内容很大,比如几个 GB,就需要分块上传,这时上传分为多个请求,每个请求只上传部分内容,这样可以保证更高的效率和成功率。

如果是整体上传,实际是调用 Put Blob 请求,这时上传的内容就是文件完整内容,因此完全符合前面描述的MD5 完整性检查工作过程,也就是最终既会做验证,Blob 也会有 MD5 值。

但如果分块上传,实际是多个 Put Block 请求加上一个 Put Block List 请求组成。每个 Put Block 请求只上传部分内容,因此这类请求里的 MD5 只能针对当前上传内容,不能作为最终 Blob 的 MD5 值。而 Put Block List 请求的内容是一个列表,包含前面所有上传 Block 的标识,因此这个请求里的 MD5 值也只能是对这个列表做完整性检查。但是所有这些请求都验证成功时可以保证内容的完整性。所以验证是有的,但 Blob 没有MD5 值。

目前出于性能考虑,Azure 存储服务不会汇总前面请求里的所有 Block 的内容来计算整个 Blob 的 MD5 值,但提供了一个特殊的请求头部 x-ms-blob-content-md5,服务端会将该头部属性值设置为 Blob 的 MD5 值。因此客户端只要在最终的 Put Block List 请求里设置了整个内容的 MD5 值到 x-ms-blob-content-md5,就可以保证验证,并且 Blob 也有 MD5 值。

因此分块上传基于 MD5 的完整性检查的工作过程是:

1、将上传文件分成多块

2、将每一块以 Put Block 请求发送,并计算当前块的 MD5 值设置到 Content-MD5 头部

3、当所有块都发送完成后,发送 Put Block List 请求

    class="list-paddingleft-2">
  1. 计算整个上传文件的 MD 值并设置到 x-ms-blob-content-md5 头部

  2. 将前面发送的块的标识组成列表作为请求的内容

  3.  计算块标识列表的 MD5 值设置到 Content-MD5 头部

4、对于所有请求,服务端根据当前请求里的内容计算 MD5,并对比请求头部中的 Content-MD5 值,相同则验证成功

5、然后将 Put Block List 请求里的 x-ms-blob-content-md5 的值赋予 Blob 的 MD5 属性

总结来说,有两个问题需要注意:

 

1/如何判断是否做完整性验证?

取决于请求的头部 Content-MD5,有则验证,否则无验证。注意:

1.Put Blob 请求里面 Content-MD5 和 x-ms-blob-content-md5 效果一样。

2. 分块上传发送 Put Block List 请求时,如果把整个文件内容的 MD5 值设置给了 Content-MD5,那么会验证报错。因为 Content-MD5 只用于当前请求内容的验证。

2/如何判断 Blob 是否包含 MD5 值?

整体上传时,如果当前请求的 x-ms-version 大于等于 2012-02-12,那么即使客户端没有设置 MD5 值,服务端也会自行计算并赋予 BlobMD5 属性。

分块上传时,就取决于 x-ms-blob-content-md5 是否有值。

立即访问http://market.azure.cn

发表评论
用户名: 匿名