今天我们继续转战学术圈之外的广大风景,为大家介绍一篇博客文章。今天的文章是由英国布里斯托的ForgeRock公司安全架构师Neil Madden(他也是API Security in Action一书的作者,但我们公众号真的没有帮他打广告!!!)撰写、关于现实世界中密码学安全的一篇小文
在BBC的科幻剧《神秘博士》中,有这么一个神奇的psychic paper,它其实是一张空白卡片,但是一旦出示这张卡片,看到的人会被操控,自觉脑补想要看到的内容(嘿嘿嘿过江通行证了解一下)。我们的作者Neil Madden发现在Java的ECDSA签名校验机制中也存在这么个神奇的操作,允许攻击者随意伪造相关SSL证书或SSL握手包,这个相关问题已经确认为CVE-2022-21449
*** 漏洞提示:所有 Java 15, Java 16, Java 17, Java 18 的用户需要考虑相关风险,及时升级到April 2022 Critical Patch Update
关于DSA和ECDSA签名的密码学知识,我们不在此处赘述,只想顺便提示一下需要复习相关知识点的同学,我们在CCS 2018的论文K-Hunt: Pinpointing Insecure Cryptographic Keys in Execution Traces中有一个非常有趣的DSA误用的例子,可以配合今天的文章一起温习,非常有趣:
(EC)DSA类的签名是一对等长的数值(r, s),在验签的数学运算中,我们并不假定r或者s有什么特殊性质,只根据标准的签名和验签方式进行运算。然而,如果这两个数值均为0会发生什么情况呢?
假设验签过程忽略了r或者s为0的情况(在Java的ECDSA验签中正是如此),攻击者可以制造一个非法的签名,令r和s均为0,导致验证总是成功,这是为什么呢?在Java的密码算法库实现中,在验签过程中首先要涉及到求s的模逆(modular inverse),这个过程中会使用到费马小定理:
然而如果x的值是0,那么这个计算就毫无意义。实际上,在椭圆曲线密码学里面,r和s均为0同样会导致在运算过程中出现无穷远点(infinity point),算法本身也规定了一旦出现这种情况即可认定是无效签名,但是Java的密码学算法库依然没有检查这个问题!
Neil Madden还深挖了为什么这个问题只影响Java 15以后的版本,他发现受影响的版本中的ECDSA验签过程都是用Java代码重写的(其实目前看起来只是Oracle家的JDK受影响,不知道OpenJDK有没有类似问题),而此前的版本都是用C++写的(这是硬件厂商的阴谋吗?让性能更烂的Java代码来帮助CPU和内存大卖?)
当然,Neil最后还是推荐大家都尽量使用更为健壮的Edwards-Curve Digital Signature Algorithm (EdDSA) 等签名算法,而避免使用(EC)DSA这类一不小心就会用错的算法。
博文地址:
https://neilmadden.blog/2022/04/19/psychic-signatures-in-java/
原文始发于微信公众号(安全研究GoSSIP):G.O.S.S.I.P 阅读推荐 2022-04-21
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论