这周,NSA报告了一个微软的高危漏洞 – CVE-2020-0601.
国外一下子闹得沸沸扬扬,微软也在一天后就提供了Patch更新,让大家升级。
我花了一天的时间探究了一下,并且研究其对我们产品的影响。以下是几篇我参考的文章:
《NSA的报告》
《CVE-2020-0601: THE CHAINOFFOOLS/CURVEBALL ATTACK EXPLAINED WITH POC》
《Proof-of-concept exploits published for the Microsoft-NSA crypto bug》
《Thomas’s summary about the root cause》
我抽空看了一眼国内,恩……都是抄国外的这几篇……所以我也就不引用了。
这个缺陷的根本问题,是微软的CryptoAPI对于ECC证书的验证方式存在漏洞。
微软的CryptoAPI在检查ECC证书时,检查公钥,检查DoD advisory,检查去曲线方程式,但是没有检查基本点G。
我虽然写不太懂,但是在上述第四篇文档中,有非常详细的说明:
首先,椭圆曲线的方程式类似于:
y^2 = x^3 + ax + b mod p
a、b、p都是约定的参数,比如在P-256中,a = -3,b 是(ee35 3fca 5428 a930 0d4a ba75 4a44 c00f dfec 0c9a e4b1 a180 3075 ed96 7b7b b73f),p是(2^256 – 2^224 + 2^192 + 2^96 – 1)。
还有一个基本点G。这个G生成了所有后续需要的东西。
ECC中的私钥就是简单的 k mod p,公钥就是 kG。而标准上,所有人在使用P-256的ECC时,G都是一样的。也就是基于这个“常识”,我认为微软才没有去检查这个G。
好开始干坏事。
我们是很容易拿到公钥的,我们称其为Q。然后我们成私钥是x,那么Q = xG(这里xG不是乘法,是变换的意思)。我们不知道x,也回推不到x。
但是,我们可以换个思路,不要推出x,而是找一个新的x’G’,让Q=x’G’。
而这个过程,其实是重新定义了一个新的椭圆算法,只不过我们知道私钥x’,然后让它的公钥和之前一样Q。
有了私钥之后,你下一步就可以签发证书了。那这本证书很明显,公钥是一样的,DoD advisory也可以是一样的,曲线方程式也是一样的(指方程式本身,不是说值),不一样的是基本点G,如今已经变成G’。但是吧,微软不查。
所以微软信任这本证书,进而用户的应用程序(使用微软CryptoAPI来检查的,比如IE和Chrome)你可以用你的私钥解密任何用你的算法加密的流量了。
注意一点,微软也不是一上来就不检查G’的,但是在公钥和G的组合通过了之后(比如访问了一个正常的证书),那么微软会把它们记载Cache中,下次来直接找Cache,所以才会忽略掉对G值的检查。
