Java 作为当前最流行的编程语言之一,常被用于企业级应用开发中。
近日,安全公司 ForgeRock 的研究员 Neil Madden 发现在 Java 15、16、17、18 版本的 ECDSA(椭圆曲线数字签名算法)签名验证中存在一个严重漏洞,黑客可以通过该漏洞轻松地伪造 TSL 证书和签名、双因素身份验证消息等,以及对文件和其他数据进行数字签名。
对此,Neil Madden 甚至将该漏洞比作科幻剧《神秘博士》中经常出现的空白纸:
《神秘博士》中有一个反复出现的情节装置,即医生通过出示一张实际上完全空白的“纸”来摆脱困境。这种纸也被称之为“通灵纸”,这使得看着它的人可以看到医生想让他们看到的任何东西,如:安全通行证、搜查令或其他。
这场景放在 Java 这门语言上,意味着黑客可以透过有问题的 Java 版本,向用户展示“非常真实”的加密通信、身份验证令牌、代码更新等等,而用户根本察觉不到有任何的异常。
不过好在 Oracle 发布了一则《重要补丁更新公告-2022 年 4 月》的说明,在 520 个新安全补丁中,对于 Java 漏洞也进行了修复,在此也呼吁使用 Java 15、16、17、18 的开发者或企业尽快进行更新。
ECDSA 漏洞
所谓 ECDSA,是指使用椭圆曲线密码(ECC)对数字签名算法(DSA)的模拟。与 RSA 或其他加密算法相比,ECDSA 的一个关键优势是它生成的密钥更小,使其非常适合用于包括基于 FIDO 的 2FA、安全断言标记语言(SAML)、OpenID 和 JSON 在内的标准中。
针对这一漏洞,Oracle 将其编号为 CVE-2022-21449,严重性评级为 7.5(满分 10)。不过,安全公司 ForgeRock 最早在 2021 年 11 月 11 日发现此问题时,将其评为 10 级漏洞。
Madden 解释道,“很难夸大这个漏洞的严重性。如果你将 ECDSA 签名用于这些安全机制(SSL、JWT、WebAuthn)中的任何一个,并且如果你的服务器在 2022 年 4 月重要补丁更新 (CPU)之前运行任何 Java 15、16、17 或 18 版本,那么攻击者可以轻而易举地完全绕过它们。现实世界中几乎所有的 WebAuthn/FIDO 设备(包括 Yubikey)都使用 ECDSA 签名,许多 OIDC 提供商使用 ECDSA 签名的 JWT。”
与此同时,来自 Infosec 的专家 Thomas Ptacek 甚至将这一漏洞描述为“年度加密漏洞”。因为这个漏洞非常容易被利用,而且存在明显的编程错误。
漏洞原理
简单来看,ECDSA 签名由两个值组成,称之为 r 和 s。要验证签名是否有效,必须检查涉及 R 和 S 的等式,即签名者的公钥,以及消息的加密哈希。
根据安全公司 Sophos 解释,验证步骤如下:
S1:选择一个介于 1 和 N-1 之间的密码健全的随机整数 K。
S2:使用椭圆曲线乘法从 K 计算 R。
S3:万一 R 为零,请返回步骤 1 并重新开始。
S4:从 K、R、要签名的哈希和私钥计算 S。
S5:万一 S 为零,请返回步骤 1 并重新开始。
理论上,当等式两边相等时,可以验证通过,签名有效。如果不对等,那说明对方不是自己人,不值得信任。但是这个相等也是有前提的,就是 r 和 s 的值不能为零。这是因为如果 r 或者 s 有任何一个值等于 0,那么通过验证的公式,只会有以下结果:0 = 0 X(来自私钥和散列的其他值),无论 X 的值是什么,等式都会成立。这意味着开发者只需提交一个空白签名即可成功通过验证检查。固然,这个值不能为零。
而此次 Java 中 ECDSA 的漏洞也是出现在这里,其应用的签名验证没有检查 R 或 S 值是否为零。
值得庆幸的是,Java 15 及以上版本应用率并不像早期版本那么广泛。据安全公司 Snyk 在 2021 年 2 月和 3 月收集的数据显示,企业采用 Java 15 的仅占 12%。多数企业还停留在 Java 8 等旧版本中。不过,使用任何受影响的 Java 版本也需要及时更新 Oracle 最新发布的补丁,详见:https://www.oracle.com/security-alerts/cpuapr2022.html。
参考:
https://neilmadden.blog/2022/04/19/psychic-signatures-in-java/
https://www.theregister.com/2022/04/20/java_authentication_bug/