你的数字签名会被撞破么?——安全 hash 的攻与防

安全 hash 函数在信息系统中有相当广泛的应用,特别是用于消息签名来保护消息的完整性和不可抵赖性等任务,可以说安全 hash 函数是现代应用密码学最重要的基石之一。如果安全 hash 函数出现安全问题,那么整个应用密码体系乃至整个互联网的安全都受到严重影响,包括软件发行、网络支付、设备升级等等。安全 hash 函数面临的最大技术安全威胁是同谋碰撞攻击,但我们也发现国内不少厂家的自制协议中存在着大量不正确的安全 hash 应用,导致可以利用简单的方法攻破其防护。近些年随着计算机性能的 提高,针对 MD5、SHA1 函数的碰撞攻击研究也进展迅速。而国内由于现实情况,替 换 MD5/SHA1 的代价高昂,很难在短期内能解决。MD5/SHA1 碰撞究竟会对现有的 信息系统产生哪些威胁?本文对 MD5/SHA1 的碰撞攻击及其应用场景进行讨论,给出了具体的攻击实例,同时给出了缓解措施。我们指出,在进行严格的约束消除同谋碰 撞的条件下,要攻破 MD5/SHA1 依然是一个非常艰巨的任务。尽管如此,这样的机制只是给了厂商难得的喘息时间,我们依然督促各厂商尽快升级到更安全的 HMAC-SHA256。

 

1.MD5/SHA1 算法简介

 

密码学中的安全 hash 函数与普通的 hash 函数有着相当大的区别。在典型数据结构hash_map、hash_set 中所用到的 hash 函数,只需要将 key 映射为一个索引即可,即使产生了碰撞,也可以采用开散列或者闭散列的方式进行处理。密码学中的安全 hash 函数[1]要求则严格的多,至少需要满足三个性质:(1)抗碰撞攻击(2)抗原根攻击 以及(3)抗第二原根攻击。抗碰撞攻击是指,寻找两个不同的串 x 和 y,使得 hash(x)=hash(y)是困难的。抗原根攻击是指,在 hash(x)=s 中,已知 s,求 x 是困难 的。抗第二原根攻击是指,已知 hash(x)=s,求一个异于 x 的串 y,使得 hash(y)=s 是 困难的。只有满足了以上三点的 hash 函数才有资格成为安全 hash 函数。

 

MD5/SHA1 是用途非常广泛的安全 hash 函数。他们的输入是任意串,输出是 128/160bit 长的散列值。MD5 和 SHA1 在 1992 年和 1993 年被发明出来,在相当长 一段时间内,他们被认为是安全的。2004 年和 2005 年,研究者发现了对他们的攻击 方法,减少了特定情况下发现碰撞的计算代价。在 2007 年首次提出了利用 MD5 碰撞 伪造 CA 证书的理论方法,2008 年这种攻击方法得到了验证,攻击者成功伪造了合法 的 CA 证书。而针对 SHA1 的攻击方法则一直停留在理论中,直到 2017 年初,对 SHA1 的成功碰撞攻击才首次公开出来。

 

这里简要描述 MD5 的计算过程,以便读者理解。SHA1 的计算过程十分相似: 首先,加入补位,使之 bit 长度模 512 的余数为 448(512-64)。接下来将长度表示 为小端序,附在后面(大于 64bit 只取低 64bit)。此时 bit 长度是 512 的倍数。接下 来依次处理每个 512bit 的块。在处理过程中不断更新 MD5 的内部状态(128bit)。 在处理完所有的块后,将其内部状态输出,作为最后的散列值。

 

2.针对安全 hash 的碰撞攻击

 

在某些情况下,攻击者需要构造一个串 y 使得 hash(y)为一指定的值 s。此时攻击者只 能控制 y,那么此时若要寻求一个满足 hash(y)=s 的实例,则属于原根攻击。对 MD5/SHA1 的原根攻击目前尚无好的计算方法,只能依赖彩虹表、字典或蛮力搜索, 攻击复杂度相当高(MD5 的状态空间是 2^128,蛮力搜索要计算 2^128 次 MD5)。

 

在另外一些情况下,攻击者可以同时控制两个输入串 x 和 y,使得 hash(x)=hash(y), 从而欺骗基于 hash 的验证系统。这种情况我们称为“同谋碰撞”。同谋碰撞是可以使 用“生日攻击”大幅度减少运算量的。以 MD5 为例,借用生日攻击,我们不需要枚举 所有 128bit 的串计算 MD5 值以求碰撞,只需要计算 2^64 次 MD5 值即可有 50%的 几率找到这样的 x 和 y。

 

MD5/SHA1 碰撞具有添加后缀依然碰撞的性质: 若 hash(A)=hash(B),则 hash(A+S)=hash(B+S) 但是并不满足增加前缀的性质,即 hash(A)=hash(B)推不出 hash(S+A)=hash(S+B)

 

2.1 长度扩展攻击

 

由碰撞的后缀延伸特性导致的一种简单易行的攻击是长度扩展攻击(Length Extension Attack) [4]。例如,某些基于 MD5 的协议使用了如下形式的签名值 sign =hash(secret + message)

 

其中的 secret 是密钥。在计算出签名值 sign 后,客户端将 sign 和 message 一起提交 给服务端。在某些情况下,攻击者可以同时获得签名值 sign 和明文 message,并且拥 有在明文尾部附加任意串的能力。此时,攻击者可以直接利用 MD5 的性质,在明文尾 部附加恶意部分 s,并直接从原 MD5 值计算

 

sign' =hash(sign, s) = hash(secret + message + s)

 

这样构造出来的新请求 message+s 拥有合法的签名 sign',因此是能够通过 MD5 签 名校验的,但是包括了攻击者注入的恶意部分 s。这种攻击在某些 CTF 题目中也有涉及 [5]。在某些情况下长度扩展攻击可以用于绕过基于 MD5 的身份认证 [6]。由于 SHA1 或者其他的安全 Hash 大部分具有这样的性质,所以将 MD5 调换为 SHA1 或其他安全 Hash 也大都是无效的。

 

所有可能被长度扩展攻击的数字签名协议应该立即升级成第四节中所述的 HMAC-SHA256 算法,因为有很大可能黑产已经在享用你的服务了。

 

2.2 前缀碰撞攻击

 

对于 MD5/SHA1 更复杂的攻击目前主要有共同前缀碰撞攻击(Identical PrefixCollision)和选择前缀碰撞攻击(Chosen Prefix Collision)。共同前缀攻击是构造 两个不同的消息 s1 和 s2,他们由相同的前缀,和不同的尾部“碰撞块”组成。前几天 震惊世界的 SHAttered 攻击是对 SHA1 进行的共同前缀攻击。选择前缀攻击则是构造 两个不同的消息 s1 和 s2,他们不必有共同的前缀,但是经过在尾部附加不同的“碰撞 块”后,两个消息的散列值相同。选择前缀攻击是包括共同前缀攻击的,因此共同前缀 的攻击代价小于选择前缀攻击。在 Marc Stevens(SHAttered 作者)2009 年的文章中对此类攻击的计算代价总结如表 1。

表 1:MD5 和 SHA1 的两种不同攻击的计算代价

 

这里的单位是需要计算的 hash 的次数。例如 2004 年之前,对 MD5 的平凡攻击(生 日攻击)需要蛮力计算 2 的 64 次方次 md5 hash。在 2009 年时,对于 MD5 的共同 前缀攻击计算代价是 2 的 16 次方次 MD5 hash,对 SHA1 的则是 2 的 52 次方。不难 看出,无论是共同前缀攻击,还是选择前缀攻击,都可以被应用在同谋碰撞攻击中。由 于共同前缀攻击和选择前缀攻击的研究进展迅速,同谋碰撞攻击逐渐成为数字签名体系 最大的威胁。

 

计算复杂度和最后构造出的碰撞结构有很大关系。对于共同前缀碰撞攻击,由王小云教 授提出的攻击方法需要构造两个碰撞块,第一个碰撞块由生日攻击得到,目的是使得计 算完第一碰撞块后的 hash 内部状态的差分满足特定形式。第二个碰撞块则由对差分路 径的搜索得到。因此构造共同前缀碰撞攻击只需要两个碰撞块。对于选择前缀碰撞攻击, 需要构造多个(>=2 个)碰撞块。第一个碰撞块的作用相同,后续的碰撞块则对第一个 碰撞块计算完成之后内部状态的区别做逐一修正。在唯一一份公开的选择前缀碰撞代码 [2,3] 中,这个后续碰撞块的长度指定为 9,意为需要构造 9 次修正块,以完成一次碰 撞攻击。长度越短,对于每个碰撞块的要求就越高,计算所需的时间也指数级提高。在 长度为 9 时,计算可以在普通计算机上运算几小时即可完成。

 

对于 MD5 碰撞的研究主要关注与快速发现 MD5 碰撞。王小云教授的著名工作[7]等, 以及谢涛的后续工作[8]等,使得在短时间内构造简短的 MD5 碰撞成为可能。对 SHA1 最著名的攻击是最近的 SHA1 Shattered 攻击,是一种共同前缀碰撞攻击 [9]。另一方 面,利用选择前缀攻击,可以伪造 X509 格式的 CA 证书 [10],以及构造多个消息的 碰撞“Herding Attack”,可以用于“预测”任何一次的美国总统大选结果。 此外,对 于攻击签名机制,还有一些由于签名机制实现不当而产生的漏洞和对应的攻击方法。下 面我们简要介绍一下选择前缀碰撞攻击的能力,然后再讨论如何利用择前缀碰撞攻击, 最后回顾一下对于基于 hash 的签名机制实现不当而产生的攻击。

 

3.MD5 的 ChosenPrefix Collision 攻击

 

对于两个给定的不同前缀 p1 和 p2,CPC 攻击可以构造出两个后缀 m1 和 m2,使得 hash(p1+m1) = hash(p2+m2)
而且 p1+m1 的长度和 p2+m2 的长度相等。

 

举个例子,令 p1=“希拉里会当选”,p2=“川普会当选”。在大选之前先利用 CPC 攻击,构造出两个后缀 m1 和 m2,然后计算他们的 MD5 值 v=MD5(p1+m1)=MD5(p2+m2)。然后告诉世人本次大选结果的 md5 值是 v。在真正结果揭晓后,若希拉里当选,则展示 p1+m1,否则展示 p2+m2,即可完成预测。 当然实际场景下没有那么简单,任何人看到“XXX 当选”后面那串毫无意义的后缀字 串都会产生质疑。在实际攻击场景中往往需要一个可以在末尾附加额外数据的数据结构 上进行 CPC 攻击,例如 PE 可执行文件、ZIP 压缩文件、JPG 图像文件等末尾都可以加 入后缀且不影响正常使用。

 

利用 CPC 攻击,还可以构造多个消息的碰撞。以三个消息为例(图片来自[9]):

 

 

IHV0 是 MD5 默认的初始状态。m1/m2/m3 是三个不同的前缀,经过 MD5 运算后得 到了三个不同的 MD5 状态(值)IHV1、IHV2、IHV3。此时先用 CPC 攻击 m1 和 m2, 生成 padding c1 和 c2,他们有共同的 MD5 值 IHV4。此时对 m3 做平凡的补长 p3, 生成 IHV5。再从 IHV4 和 IHV5 开始使用 CPC 攻击,即可得到 c4 和 c5。此时 MD5(m1+c1+c4)=MD5(m2+c2+c4)=MD5(m3+p3+c5)

 

而且 len(m1+c1+c4)=len(m2+c2+c4)=len(m3+p3+c5)。

 

一份公开的 CPC 攻击源代码是由 Mark Stevens 编写的 HashClash [2],支持使用 CUDA 来加速 CPC 攻击中的生日攻击部分,然而这份代码目前不能很好工作。一份能 工作的代码在 [11]中可以找到。由于 CUDA 接口的升级,[2,11]中的 CUDA 部分均不能正常编译。在做了一些修正后我们把现在可以工作的版本公布在 [12]中,供网友实验。

 

使用 [12],我们构造了两组 hash 碰撞,大小分别为 704 字节和 1048576 字节(1Mb)。 在我们双路 E5-2650V3 的服务器上,我们使用了 30 个核心和 3 块 K1200 加速卡,运算 6 小时可得到一组碰撞。其中使用加速卡进行生日攻击的时间只有不到十分钟。

 

A.伪造 CA 证书


在 MarcStevens 2009 年的工作中,展示对 CA 证书的攻击使用的是选择前缀攻击。 图 1 展示了伪造 CA 证书的原理 [10]。

 

图 1 CA 证书的伪造过程

 

图 1 左侧是合法的网站证书结构,右侧是需要伪造的 CA 证书结构。进行攻击时,攻击 者可以同时控制左侧的合法网站证书结构,和右侧的伪造 CA 证书的结构。这里攻击者 需要对头部几个域(serial number/validity period)等进行"猜测",但是由于很强的可 预测性,做这个猜测并不难。攻击者通过对发行证书的机构进行反复观测(反复申请证 书),发现 1. 序列号是线性增加的并且 2. 有效期是可预测的。因此攻击者可以计划一个攻击的时间,并猜测那个时间段可能出现的序列号范围,并构造其对应有效期,构造出一批可能的合法证书头部,作为选择前缀攻击的消息前缀。而对于右侧伪造的 CA 证书,则构造了一个合法的 CA 证书头部。接下来攻击者就进行大量运算,计算出一批 碰撞。接下来再对做出的碰撞进行尾部补全,得到一批“合法网站证书”和“伪造 CA 证书”,并且从“合法网站证书”中取出 RSA 公钥。最后,在攻击者精心计划的攻击时间,去申请网站证书。如果申请下来的网站证书的序列号/有效期恰好匹配到攻击者 预测范围内的某一个证书,那么攻击就完成了,生成了一个完全“有效”的伪造的 CA 证书。

 

2007 年,Alexander Sotirov 和 Marc Stevens 的团队使用了 200 台 PS3 主机进行了基于 MD5 CPC 攻击的 CA 证书伪造攻击。每一次计算耗时 1-2 天,在失败了 3 次后, 第四次终于成功。

 

B.SHA1 SHAttered 攻击


今年 2 月,SHA1 的碰撞攻击 SHAttered 首次公开在互联网上。SHAttered 攻击属于共同前缀攻击,其展示形式非常直观--两个大小相等、SHA1 值相同,但是显式效果 迥异的 PDF 文档。

 

图 2 SHAttered 攻击的实例

 

该攻击的难点有二,一是如何完成 SHA1 共同前缀攻击,二是如何使用共同的前缀和后缀,以及不同的碰撞块,构造两个合法的 PDF,并且他们的显示效果不同。

 

第一个问题,Marc Stevens 已经为此研究数年。这次他联合了 Google 的工程师终于把算法变成现实。在这次攻击中,他们使用了 CPU 来计算碰撞块的第一个 block,使用 GPU 来计算碰撞块的第二个 block。碰撞块的第一个 block 的第一次碰撞消耗了 3583 核-年的计算量,第二次碰撞消耗了 2987 核-年的计算量。在第二阶段,除了 CPU 外,还是用了 GPU 集群进行运算。GPU 集群的计算量相当于 114 块 K20 计算一年, 或是 95 块 K40 计算一年,或是 71 块 K80 一年的计算量。如果使用商业的云 GPU 服 务,租用 71 块 K80 计算一年,就将耗费 56 万美元。

 

对于第二个问题,该攻击做了非常巧妙的构造。我们借用热心网友的回答 [17] 来做分析。首先,SHAttered 攻击是一个共同前缀攻击,所以构成的 pdf 一定是有一个共同 的 pdf 头部,参见图 3。

 

图 3 SHAttered 攻击的 PDF 结构

 

两个 PDF 的头部共同部分包括:PDF 文件头和 image 对象的一部分。在 image 对象 中,包括了属性表引用、content 结构,和属性。该攻击构造了一个巧妙的 content 结构,在这个结构中包含了一个 JPEG 图片。碰撞块 Magic block 1 和 Magic block 2 就位于这个 JPEG 图片内部 metadata 的部分,见图 4。

 

图 4 JPEG metadata 部分的结构

 

注意其中的 FFFE comment 处。FF FE 这两个字节代表了 comment 段的开始,其后 的两个字节代表该 comment 段的长度。在图 4 中出现了两个 comment 段,第一个段的长度是 0x24,用该 comment 段的起始地址 0x99+0x24 可以得到第二个 comment 段的地址 0xBD。可以看到 0xBD 位置处依然是一个 FF FE 标签,代表另一个 comment 段的开始。这个 comment 段的长度在两份 pdf 中就不相同了,在第一 份 pdf 中,这个长度是 0x173(指向 0xBF+0x173=0x232),而在另一份 pdf 中,这 个长度是 0x17F(指向 0xBF+0x17F=0x23E)。0x232 开始的位置是一个很长的区段, 而 0x23E 开始的部分是一个非常短的区段。其后还有一些精心布置的区段,它们的字 节表示都一样,但是由碰撞块的第一字节引起差别后,所能表示的结构不同,从而使得显示出来的图像不同。

 

C.对网盘的“秒传”机制进行攻击 总所周知,网盘的“秒传”机制可以大大减少文件上传的时间代价。“秒传”机制往往 使用 hash 函数生成文件的摘要值来作为文件特征值,判断是否可以使用“秒传”功能。 另一个影响“秒传”机制的参量是文件大小。往往大文件会触发“秒传”机制,而小文件不一定触发。

 

这里我们使用网易网盘、115 网盘、城通网盘、腾讯网盘、中国移动彩云网盘、Box.com、 Dropbox 进行测试。除了网易网盘外,其他网盘均提供了对 txt 后缀文件的预览功能。 我们使用了一对 704 字节的碰撞和一对 1MB 字节的碰撞作为实验文件,将他们上传到 网盘中,使用下载、预览功能分别下载、预览这两个文件,测试各个网盘能否区分这两个大小相等而且 MD5 值相同的文件。结果如下表。如果下载下来的两个文件是相同的, 则证明网盘无法区分这两个文件,我们将这个测试结果标记为“冲突”,否则标记为 “不冲突”。

 

 

可以看出,网易网盘、城通网盘和彩云网盘完全无法区分 MD5 碰撞的文件。

 

著名的 virustotal 网站曾经使用 MD5 作为文件判重的标准以减少运算量。但是在 CPC 攻击出现之后,攻击者就可以通过先提交善意文件再传播恶意文件的方式躲避来自virusltotal 的报警。因此 virustotal 迅速进行了修改,使用 SHA256 的散列值作为文件特征。

 

目前很多安全厂商依然在使用 md5 用于恶意代码识别,这里需要有额外的判重机制。 由于 MD5 碰撞基本上都是属于上文所述的同谋攻击,因此如果相同 MD5 值下有一个 样本是恶意的,其他的样本一般也是作为攻击的中间环节而存在,将所有样本都报警也是一种可行的办法。

 

D.攻击基于“尾部附加 key”形式的 MD5 签名进行攻击


我们先回顾上一篇文章 [13]中所述的在线支付协议中基于 MD5 的签名机制。以请求 “c=C&b=B&a=A”为例。为了签名这个请求,先将请求解析为 key-value 对: {"c":"C","b":"B","a":"A"}


然后按 key 的字典序进行排序并连接


a=A&b=B&c=C


附加上 key


a=A&b=B&c=C&key=this_is_a_secret


计算 MD5 值 MD5(a=A&b=B&c=C&key=this_is_a_secret)=0a1d218f9b2b029c84c84458bb6 dbc00


形成最终的请求


c=C&b=B&a=A&sign=0a1d218f9b2b029c84c84458bb6dbc00

 

这样的请求存在于从支付平台返回给商户服务的支付结果异步通知中。商户的验签过程通常是这样的:


1、从参数中去掉 sign 域

2、将剩余参数 decode,将每个接口的参数按照 key 值升序排列;

3、将排好序的参数按照 key=value&的形式链接为字符串;

4、将生成的字符串尾部附加上密钥“key=token”,然后做 MD5;

5、检查 MD5 值是否等于 sign 域。若相等,则证明消息未被窜改。

 

这里我们注意到:验签时的参数列表默认是对“所有”参数验签。如果攻击者可以在消 息中插入一个域,那么就可以使得验签时也包括这个参数。由于此类系统的复杂性,这 个请求往往很长,包括很多参数以及嵌套了许多层的商品信息。攻击者一旦找到一个参 数或者嵌套的参数可以注入,那么就可以控制异步通知的内容。为了叙述方便,我们假 定攻击者下了两个订单,订单 Id 分别为 1704176438 和 1704176439。而且攻击者可以控制参数“zzz”的尾部内容,例如将请求设置为 src 的形式: customerId=4&orderId=1704176438&service=querypay&version=1.0&zzz= 这里 zzz=后面可以是任意给定内容,这里留空也不影响。攻击者构造另一个请求 dst: customerId=4&orderId=1704176439&service=querypay&version=1.0&zzz= 这里只简单修改了 orderId 以演示效果。然后通过 CPC 攻击计算得出一组碰撞 src.coll 和 dst.coll。由于攻击者能控制 zzz 域,于是将 src.coll 进行真实支付,获得支付平台 的签名 sign,然后将其异步通知中的订单号做简单修改,从 1704176438 改为 1704176439,作为伪造的异步通知提交给商户服务器。由于 src.coll 和 dst.coll 的 MD5 值是相等的,所以他们在尾部附加上商户的密钥之后做 MD5 值依然是相等的(MD5 碰撞的尾部附加性质)。因此伪造的异步通知也是有效的。如果商户服务器不 去查账而是相信支付平台的异步通知,那么攻击者成功的用一个订单的金额完成了两个订单。

 

此外,之前也出现过针对微软 msi 签名机制不完善/双签名机制的攻击,构造具有“合 法签名”的恶意代码。也发现了真实的利用 CPC 攻击传播的恶意代码的实例。感兴趣 的读者可以参考 [14]。

 

4.安全的使用安全 hash 签名

 

首先为了抵抗 CPC 攻击,不能简单的在待签字符串后面附加密钥,而是需要在待签字 符串前后均附加密钥,即计算:
sign = hash(secret1 + string + secret2)

 

作为签名。如果只在头部附加,那么可能受到长度扩展攻击影响。如果只在尾部附加, 那么可能受到 CPC 攻击的影响。但是如果两端均附加,那么就不受到这两类攻击的影 响了。此时,为了计算一个合法的碰撞,攻击者不得不使用基于生日攻击的蛮力搜索来 进行攻击。而且如果 secret 安全地存储在云端,攻击者必须要产生大量的网络请求来 完成碰撞,这个是难以实施且易于探测的。

 

如果存在同谋碰撞攻击的可能,强烈建议前后同时都加签名密钥保护,而这也恰恰是 HMAC [15,16] 的设计实现。因此在实际应用中建议使用 HMAC 扩展算法,而不是直接使用 MD5/SHA 等算法,即使对于 SHA256 也是如此。

 

若不能直接升级到 HMAC-SHA256 算法,则要尽可能的消除同谋碰撞攻击的机会,将 攻击退化成针对一个固定 hash 值的单向碰撞攻击。在同谋碰撞攻击(共同前缀攻击和 选择前缀攻击)中,由于碰撞块的存在,需要对输入有充分的自由选择能力。若能严格 的限制参与签名的域,并且对参与签名的每一个域进行严格检查,则可以大幅度消除同 谋攻击的潜在机会。

 

真实世界中不乏易受同谋攻击的例子。这里用 AnySDK 为例。AnySDK 是一个第三方 SDK 接入工具,使用 AnySDK 可以接入许多不同在线支付平台。AnySDK 提供了一份 典型的有风险的验签代码 [17],容易受到同谋攻击威胁:


function checkSign($data, $privateKey) {

if (empty($data) || !isset($data['sign']) || empty($privateKey)) { return false;

}
$sign =$data['sign'];

//sign 不参与签名 unset($data['sign']);

$_sign =getSign($data,$privateKey); if ($_sign!= $sign){

return false;

 }

return true;

}

 

其中的 getSign 函数只是负责进行拼接待签字符串和计算 hash。可以看出,这份代码 对输入的域并没有任何限制,于是攻击者的任何输入均可进入验签过程中。这是相当危 险的,使用普通服务器运算几小时即可生成完成 MD5 CPC 的运算,生成一组可用于 发动攻击的 MD5 碰撞,而成本只需几元电费。若使用云计算平台则可进一步提高速度。 因此,这样的签名结构,搭配有缺陷的验签代码,现在已经非常危险。

 

以下是一份进行了良好的输入参数验证的示例代码,可以最大程度的消除同谋碰撞的机会:

 

functioncheckSign($data, $privateKey) {

if (empty($data) || !isset($data['sign']) || empty($privateKey)) { return false;

}
$this->params['arg1'] = $data['arg1']; $this->params['arg2'] = $data['arg2'];
if (checkArgs($this->params) == false) {

return false;

}

$sign =$data['sign'];

$_sign =getSign($this->params,$privateKey); if ($_sign!= $sign){

return false;

 }

return true;

}

 

其中通过 checkArgs 函数对 params 数组的每个域进行合法性检查,通过后再进行签名计算。

 

在实施了这些防护措施之后,同谋碰撞攻击将会近似退回到原根攻击,目前估计针对 MD5 的攻击复杂度将超过 112bit,而针对 SHA1 的攻击复杂度将超过 144bit,在可 见的近期代价依然非常高昂,不是普通机构能够承担。

 

5.总结

 

种种关于 MD5/SHA1 是否过时的讨论已经持续多年,但是由于国内的实际情况, MD5/SHA1 依然存在于我们日常生活的每个方面,要替换的过程依然漫长。我们在对 实际系统中的 MD5/SHA1 进行攻击分析后发现,在完善了验签、判重机制并尽可能消 除同谋碰撞后,其安全性短期之内还是可以得到保证的。尽管如此,这样的机制只是给 了我们难得的喘息时间,我们依然督促各厂商尽快升级到更安全的 HMAC-SHA256。 最后再次强调,所有可能被长度扩展攻击的数字签名协议(节 2.1)应该立即升级成第 四节中所述的 HMAC-SHA256 算法,因为很有可能黑产已经在享用你的服务了

 

参考文献

1.Cryptographic Hash Function,https://en.wikipedia.org/wiki/Cryptographic_hash_function

2.The HashClash Project, http://www.win.tue.nl/hashclash/

3.Create your own MD5 collisions,https://natmchugh.blogspot.com/2015/02/create-your-own-md5-co llisions.html

4.MD5 长度扩展攻击,https://zh.wikipedia.org/wiki/长度扩展攻击

5.哈希长度扩展攻击解析,ricterzheng,https://ricterz.me/posts/哈希长度扩展攻击解析

6.MD5 长度扩展攻击原理,http://blog.nsfocus.net/tech/技术分享 /2016/06/27/MD5 长度扩展攻击原理.html

7. How to break MD5 and other hash functions,http://dl.acm.org/citation.cfm?id=2154601

8. How To Find Weak Input Differences For MD5 Collision Attacks,http://eprint.iacr.org/2009/223.pdf

9. MD5 Chosen Prefix Collision,https://www.win.tue.nl/hashclash/ChosenPrefixCollisions/

10. Creating a rogue CA certificate,http://www.win.tue.nl/hashclash/rogue-ca/

11. Create your own MD5 collisions,https://natmchugh.blogspot.com/2015/02/create-your-own-md5-co llisions.html

12. MD5碰撞示例代码,https://github.com/dingelish/md5-cpc

13.支付安全不能说的那些事,百度安全实验室公众号

14. MD5碰撞的演化之路,http://bobao.360.cn/learning/detail/2577.html

15. Keying hash functions for message authentication, Mihir Bellare ,Ran Canetti , Hugo Krawczyk

16. How did the Shattered.iogroup manage to create a SHA1 collision for a PDF that is similar looking tothe original?, https://security.stackexchange.com/questions/152341/how-did-the-shattered -io-group-manage-to-create-a-sha1-collision-for-a-pdf-that

17. AnySDK签名算法及示例, http://docs.anysdk.com/integration/server/payment-notice/

收藏 评论(16)
分享到:
共16条回复 最后由bojuelind 回复于2019-05-12 02:54