MD5 是一个特别古老的知识:
老到我们都认为它的一切都是理所当然的;
老到我们看到这个名称仿佛看到的就是老掉牙的代名词。
直到前段时间我遇到了一些案例,才想起来,也许可以跟大家聊聊这个特别 “平常” 的小玩意儿~
一、为什么有这么一个话题
前几个月在处理小朋友日常视频的时候,发现视频工具提供了一个 MD5 更改的工具,下意识心说这么简单的一个功能咋还搞了个工具出来,不过转念一想,这也许就是个思维陷阱,其实听说过 MD5 的人本来就不多(只是我们身处这个行业才觉得很平常)
好奇看了一下搜索结果(是不是发现也许一个小东西也是商机):
更改 MD5 值 的原因是 有些视频平台用 MD5 来验证上传的视频是否为原创(不过,抖音这些大平台,现在早就已经不只是 MD5 了);其他还有一些网盘目前也还在用 MD5 作为文件的唯一性验证,当然也还有一些 知乎之类的网站 根据 MD5 限制图片不能重复上传。
同样我们日常工作中也有很多 MD5 进行编码的案例,比如参数合法性校验;甚至可能还有相当量的场景使用 MD5 进行密码的编码存储(等这趴结束了如果有时间可以给大家再讲个小故事);很多场景大家潜意识就会选择使用 MD5,不过不知道有没有考虑过为啥要用 MD5?
大家之所以用 MD5 对原文进行编码,其中一个原因就是因为它编码后的内容是不可逆而且具有唯一性的;这次呢我们就这两点进行展开~
这里提前解释一下,我们可以称 MD5 为编码方式、函数、散列函数、算法、摘要算法等等,不过尽量不要把他称为加密算法,哈哈
二、MD5 真的 不可逆 吗
这里可能有小可爱在想,现在不是有很多破解 MD5 编码字符串的工具吗,即使 用穷举碰撞的方式,也只是算力和时间问题,最终不都是能破解的吗?
从逻辑上先说一下结论
举个栗子
这里提供一个 MD5 字符串:c5d96e397097aac1de53abf3cd77ccd3
,看着是不是比较简单?
这个字符串哪儿来的
但是这个长度为 32 的字符串是对 60 多万字的 罗贯中版本《三国演义》进行编码得来的,如果可逆,大家试想将会发生什么~~~(这对信息论将是颠覆)
从编码过程看看为啥是不可逆的
再举个栗子
现在我们有一个函数 OUSHU()
,作用是将一组数字中的偶数数字提取出来
- 比如
OUSHU(13125718) = 28
- 我们能根据
28
推算出来原文是13125718
吗?
MD5 编码原理
脑袋放空,这趴不需要大家记忆的,只需要有个印象就行,实际几乎不太可能记得住如何计算的
如上面例子,MD5 其实是摘要算法,从目标数据中取出部分内容并加以转换作为摘要,用来代表原目标数据;
MD5 的编码原理分为多个步骤:
处理原文
a. 首先,计算出原文长度(bit)对 512 求余的结果,如果不等于 448,就需要填充原文使得原文对 512 求余的结果等于 448。填充的方法是第一位填充 1,其余位填充 0。填充完后,信息的长度就是 512*N+448;b. 之后,用剩余的位置(512-448=64 位)记录原文的真正长度,把长度的二进制值补在最后。这样处理后的信息长度就是 512*(N+1);
原文分组
假设咱们要处理的原文长度是 1024 位,那么就分为 2 组
3.设置初始值以及硬编码计算函数
a. MD5 的哈希结果长度为 128 位,按每 32 位分成一组共 4 组。这 4 组结果是由 4 个初始值 A、B、C、D 经过不断演变得到。MD5 的官方实现中,A、B、C、D 的初始值如下(16 进制):
1). A = 0x01234567
2). B = 0x89ABCDEF
3). C = 0xFEDCBA98
4). D = 0x76543210
b. 设定硬编码的计算函数,MD5 提供了如下几个函数供计算使用
1). F(X, Y, Z) = (X&Y) | ((~X) & Z)
2). G(X, Y, Z) = (X&Z) | (Y & (~Z))
3). H(X, Y, Z) = X^Y^Z
4). I(X, Y, Z) = Y^(X|(~Z))
循环加工
这个步骤最复杂,为了方便记忆,我们就不去看具体公式了(看了公式压根记不住),咱们来个简单的描述:a. 将 1024 位分为 2 大组,每个大组再分为 16 小组,每个小组依次调用 F、G、H、I 函数进行计算
b. 每个小组的内容 分别跟 A、B、C、D 参数一起当做 F、G、H、I 函数的参数,进行调用运算,运算出来的结果形成新的 A、B、C、D
c. 所有的原文分组都用 F、G、H、I 调用完以后,最后更新完毕的 A、B、C、D 就是我们要的结果
拼接 A、B、C、D,并转换为 字符串,就是我们要的 MD5 结果了
是不是脑瓜嗡嗡的,其实是正常的
- 大家如果脑子有一个印象,就是 MD5 是经过固定的几个函数公式进行循环调用计算得来的,那就算 80 分了
- 如果还能记得大概的循环计算过程,那是超出预期了,能得 100 分
- 如果知道了 A、B、C、D 如何计算得出新的值 以及 新的值如何参与下一轮运算,那你是偷题了
聊完可逆性的问题,我们来看看唯一性~~~
三、MD5 真的 唯一 吗
前些年,大家对 MD5 的唯一性其实还是很信任的,直到如下的案例越来越多~~~
先看两个图片
https://s3-eu-west-1.amazonaws.com/md5collisions/ship.jpg
https://s3-eu-west-1.amazonaws.com/md5collisions/plane.jpg
他们的 MD5 值都是:253dd04e87492e4fc3471de5e776bc3d
为啥呢?其实也很简单,我们假设 MD5 是一个 OUSHU() 偶数提取函数,比如 OUSHU(13125718) = 28
,那计算出来结果为 28
的原文除了 13125718
,是不是也有可能是 12358
,是不是也有可能是 9275138
再看一个工具
碰撞工具名称为:fastcoll
,可以根据样本数据,推算出来拥有相同 MD5 值的两份数据
如果大家尝试的时候编译遇到问题可以找我
四、MD5 还能用吗
- 不要直接用在密码等敏感场景
- 有外部输入的文件唯一性验证场景不太严谨了
- 参数校验场景在加盐的情况下还是可以用的
本文作者: wettper
本文链接: http://www.web-lovers.com/interesting-md5.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!