所以,如果只用一个哈希值就判定是同一个文件,那就比较容易会出现张冠李戴的情况。
甚至,有人还基于此提出一种哈希碰撞攻击:如果我知道一个文件的md5值,但拿不到这个文件,我通过数学计算,构造一个相同md5的文件,那岂不是就把那个文件直接给我转存过来了?如果是一个私密的文件呢?那不出事了!
百度网盘的做法
那百度网盘是咋做的呢?
首先上传一个稍微大一点的文件(小文件有计算哈希的功夫早就传完了),使用浏览器F12大法,看一下它的网络请求:
可以看到,百度网盘对文件进行了分块传输,这也是目前业界比较流行的做法,对大文件进行分块,如果网络不好断开了,下次只需要传输剩下的分块就行了,做到了断点续传。
不过注意看,在上面分块的中间,插入了一个叫rapidupload接口的请求,从名字你也可以猜出来了,这个接口肯定跟它的“秒传”功能有关系
来看一下请求的参数,是一个Form表单,有这么几个字段:
其实就是对文件的前262144个字节,也就是256KB进行计算。如果文件比这还小,那就用不着秒传了。
但奇怪的是,我扣取了文件的前256个字节,计算出来的md5,和它接口中上传的参数并不一致!
这让我疑惑了好几分钟,难道事情没这么简单?
我又打了断点在计算的位置,发现它计算的跟我计算的又是一样的,但通过网络发出去以后就变了,真是薛定谔的MD5,奇怪了!
不过,程序不是量子力学,它不会骗人,很快我就找到了问题所在:百度网盘可能担心自己的路数被发现,对文件的MD5和切片MD5都进行了加密!