Azure 进阶攻略 | 文件完整性,你打算如何证明?
假设你是一位独立软件开发者,通过自己的网站提供软件下载。网站完全托管在 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 请求
计算整个上传文件的 MD 值并设置到 x-ms-blob-content-md5 头部
将前面发送的块的标识组成列表作为请求的内容
计算块标识列表的 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 是否有值。

Azure 进阶攻略 | 文件完整性,你打算如何证明?的更多相关文章
- Azure进阶攻略丨共享访问签名是个什么东东?
Azure 进阶攻略]一经推出便受到了广大粉丝的热情追捧,大家纷纷表示涨了姿势,并希望能了解更多的攻略~根据大家的投票结果,本期,小编将为大家讲解“如何生成 Shared Access Signatu ...
- Azure进阶攻略丨Azure网络通不通,PsPing&PaPing告诉你答案
很多时候,为了解决一些问题,要查各种文档,很麻烦你造吗!做「伸手党」又容易被鄙视,这时候就需要用到[Azure 进阶攻略]啦!特此,我们推出关于 Azure 常用操作指南的系列文章,每篇涉及一个 Az ...
- Azure进阶攻略 | 应用流畅运行杜绝超载,自有一套好方法
世界上很多东西,无论交通工具.房屋建筑,甚至计算机程序,在容量方面都存在设计上的理论最大值. 比如火车,正常情况下是这样的.舒适地坐着,安静地读一本书,时不时抬头若有所思地远眺车窗外风景,满满的文艺范 ...
- Azure进阶攻略 | 下载还是在浏览器直接打开,MIME说了算!
多年来,从一开始的网络菜鸟发展成 Azure 云专家,想必你一定学到了很多知识.不知道在这个过程中你自己是否遇到过,或者被人问到过类似下面这样的问题: 同样是直接点击网页上提供的 .mp4 视频文件链 ...
- Azure进阶攻略 | 该如何唤醒你?因内核超时而沉睡的Linux虚拟机!
周五下午,当你收拾好东西准备下班,奔赴 Happy Hour 时,突然接到开发团队的电话: 对方:伙计救命啊,我在搭建开发环境,但 Azure 上的 Linux 虚拟机无法启动! 你(心里想着:你要加 ...
- Azure进阶攻略 | 数据库上云:零停机、自动化
小明最近挺忙,刚刚在外地找了个新工作,正在忙着搬家.多年积攒的家当很多,根本不能潇洒地「说走就走」,于是他联系了搬家公司.专业的就是不一样,不费什么事,就把所有东西打包.运输.拆包到位了.抵达新城市的 ...
- Azure 进阶攻略 | 电脑跑分你会,但虚拟机存储性能跑分的正确姿势你造吗?
想学生时代,小编最爱做的就是研究电脑硬件,然后给自己.朋友和童鞋装机.装好后呢?当然要第一时间跑分了!各种跑分软件运行一遍,不断优化,不断测试.终于得到一个满意成绩,截图分享到网上显摆一下.当年为啥就 ...
- Azure进阶攻略 | VS2015和Azure,想要在一起其实很容易
下雨天,巧克力和音乐很配…… 大冬天,男神和捧在手里的奶茶很配…… 「驴牌」的包包,和女神的全部衣服都配…… 对于「王首富」,容易实现的小目标和一个亿是绝配…… …… 醒醒吧!!这些事情和每天只会写代 ...
- Azure进阶攻略丨如何驾驭罢工的Linux虚机网卡?
很多人的生活中,流传着一个屡试不爽,据说可以解决任何问题的百宝锦囊: 所以经常可以听到类似这样的对话: -我的电脑咋上不去网了? -重启一下电脑. -还是不行呢! -重启一下路由器. -怎么还不行-_ ...
随机推荐
- Alpha冲刺(6/10)——2019.4.28
作业描述 课程 软件工程1916|W(福州大学) 团队名称 修!咻咻! 作业要求 项目Alpha冲刺(团队) 团队目标 切实可行的计算机协会维修预约平台 开发工具 Eclipse 团队信息 队员学号 ...
- 浅谈c语言的线性表的基本操作———基于严蔚敏的数据结构(c语言版)
主要讲的是线性表的创建,插入及删除: 0. 线性表的建立,对于这类操作主要是利用了结构体的性质,对于定义的线性表的特性主要有三点:首先 Typedef struct { ElemType *ele ...
- 数位dp 简单入门
推荐博客 推荐博客 数位dp是一种计数用的dp,一般就是要统计一个区间[le,ri]内满足一些条件数的个数.所谓数位dp,字面意思就是在数位上进行dp咯.数位还算是比较好听的名字,数位的含义:一个数有 ...
- 对bootstrap模态框的小尝试
bootstrap中有一个“模态框”插件,我理解的意思就是一个具有全局遮罩的弹窗提示,官方解释是:模态框(Modal)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开父窗 ...
- poj 1664放苹果(递归)
放苹果 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 37377 Accepted: 23016 Description ...
- TreeMap读源码总结
红黑树: 定义 A red–black tree is a kind of self-balancing binary search tree in computer science. Each no ...
- forEach与jdk8中的lambda, Stream
增强for循环 :forEach 反编译后可以看到实际使用的仍然是Iterator+while遍历的 forEach的优点是写法简单,缺点是不能使用xxx.remove(e)或者iter.remove ...
- windows开机启动软件设置
开机启动软件设置 操作步骤如下: 1.按win+r,输入 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup,点击确定: 2.拖动 ...
- connect to 10.104.11.128 port 9999 (tcp) failed: No route to host
问题: iptables当找到匹配的规则时,就会执行相应的动作,而不会向下继续匹配. 可以看到https没有添加,匹配不到规则,所以就会包错 解决方法: iptables -I INPUT -p tc ...
- Zookeeper如何正确设置和获取watcher
Watcher 设置是开发中最常见的,需要搞清楚watcher的一些基本特征,对于exists.getdata.getchild对于节点的不同操作会收到不同的 watcher信息 state=-1 ...