翻译:pwn_361

预估稿费:200RMB(不服你也来投稿啊!

投稿办法:发送邮件至linwei#360.cn,或上岸网页版在线投稿

rsaphp你所知道的PHP中的公钥加密是毛病的 Python

概述

去年,我们的安全团队确认了 CVE-2015-7503漏洞,别号ZF2015-10,这是一个在利用RSA过程中,涌现的功能上的漏洞,存在于Zend框架的密码库中。

这个实际漏洞(采取PKCS1v1.5 添补方法的RSA密码“添补预言”漏洞)最初是由Daniel Bleichenbacher在1998年发布出来的。
“添补预言”漏洞许可攻击者用一个加密的,并多次发送修正过的密文到做事器(每一次得到一个添补缺点的标识),根据返回的缺点标识,有可能规复出原始信息。

人们可能希望,任何许可攻击者还原出原始信息的漏洞(“添补预言”已经被创造了超过十六年),开拓者都该当有所理解,并减小漏洞利用的可能性。

很遗憾,当我们审察PHP软件时(包括开源的和专用的),我们创造,纵然在2016年编写的运用层加密协议中,仍旧存在这种漏洞,可以通过这种方法去攻击。

我们相信造成这种结果的成分紧张有两个方面:

1.大多数开拓职员对如何在所有措辞中安全的实现公钥加密理解不足。

2.PHP的OpenSSL 扩展在默认配置下是不屈安的,但是在实际操作中,没有人会去修正默认配置。

快速办理方案:利用安全的PHP公钥加密库

如果你对这么多的“为什么不屈安”不感兴趣,你可以直接看这个:“为你的PHP项目选择一个精确的加密库”。

RSA是如何变坏的

当涉及到运用层加密,利用RSA切实其实是一个缺点。
这并不虞味着你的该当程序是完备失落败的。
无论如何,你必须避免很多RSA的履行毛病(有些是昭示的,有些不明显)。
让我们看一看一些PHP开拓职员可能会碰着的情形。

1.默认安全配置会让每个人都上当

在PHP中,大多数的RSA在履行过程中都会用到下面的两个函数:

openssl_public_encrypt()

openssl_private_encrypt()

来看一个这两个函数的原型,有一个默认配置:

OPENSSL_PKCS1_PADDING 常量见告OpenSSL 扩展:”我们想用PKCS1添补方法“。
但是我们之前已经说过了,采取PKCS1v1.5 添补方法的RSA密码,存在添补预言的弱点,这一点从1998年就已经被公开了。
由于攻击者为了规复明文,可能须要一百万个的攻击本钱,因此这种攻击更多的被普遍称为 \"大众百万攻击\"大众。

办理方案是无论你什么时候利用这两个函数,都须要利用OPENSSL_PKCS1_OAEP_PADDING常量。
这个常量会逼迫用OAEP添补方法代替不屈安的PKCS1 V1.5添补方法。

在我们的体会中,实际上没有人这么做(除非在我们团队中有某个人帮它指了出来):

Zend\Crypt didn't

Sikker (PHP security library) didn't

Pikirasa (PHP cryptography library) didn't

Minds (social network allegedly backed by \"大众Anonymous\"大众) didn't

乃至是有履历加密开拓职员,在利用RSA加密时,常常都会忘却利用OAEP。

因此,如果你须要逼迫利用公钥算法(不论作为一个开拓者,还是一个渗透测试者),并且当你们提到RSA算法,还评论辩论着”2048bit密钥够不足?或者需不须要用4096bit?“时,请先检讨你利用的添补方法吧。
你很有可能只须要几千条信息就能规复出明文,从而完备将运用程序的安全性作废。

2.直策应用RSA加密的危险性

如果你已经阅读了前面的内容,并且已经思考过,”那好,如果我仅仅记住利用OAEP,我就可以不受阻碍,直策应用RSA加密任何信息吗?”,没有这么快,你最好不要用RSA加密长信息。

当面对加密长信息时,大多数开拓者很聪明:他们会将信息分割成214-byte的信息块(对付2048bit的密钥),并且对每块分别进行加密,可以大略的将RSA的这种模式称为ECB模式。

如果你这样做,攻击者可能不会去规复出你的明文,但是正如之前所说过的,RSA很慢,罪犯可能会充分利用这个特点,去发动DDOS攻击,从而很随意马虎的扩大DDOS的影响,并且对RSA发动DDOS攻击,不须要用明显的攻击方法,你可能只须要用复制、重新排序或删除214字节块的方法,而不是创建一个解密缺点。

利用稠浊密码系统编制

最好的实现公钥密码的方法是建立一个稠浊的加密系统编制。
结合对称密码和非对称密码。
这样做有如下几个好处:

效率高:对称密码加密速率比非对称密码快很多

适用性:对信息长度没有实际限定

安全性:请看来面

1.稠浊RSA+AES

结合RSA和AES常日很有必要:

(1)用对称密钥,利用对称密码加密。

(2)利用公钥密码加密(1)中的对称密钥,从而让只有私钥的一方才可以解密出对称密钥,并利用它。

Zend\Crypt在3.1.0版本往后,就已经支付稠浊RSA-AES的加密系统编制了,并采取了EasyRSA库。
在Zend框架解释文档中,对它采取的稠浊加密方案的事情事理理解的很好。

由于现有的AES密钥大小一定,你须要加密的数据只有16、24、或者32byte,这远小于2048bit RSA最大许可的214bytes。
实际的数据加密采取的是CBC模式的AES,或者是CTR模式的AES。
对付大多数运用程序,这种加密对长度没有实践的上限。

2.稠浊ECDH+Xsalsa20-Poly1305

Libsodium 加密库利用基于椭圆曲线的DH密钥交流算法,代替RSA,用于协商共享密钥,该共享密钥被xsalsa20-poly1305用于加密和密文鉴定中。

干系功能为crypto_box()。

当你想用吸收者的公钥加密数据时(即发送者无法解密),Libsodium 的另一功能是对付每条,产生一个随机的公私密钥对,并将公钥附在密文后面,名为 crypto_box_seal()。

针对RSA的模数攻击是一个长期的威胁

RSA的安全性基于大数分解的困难性,然而,在不久的将来,这一安全担保会面对两个紧张威胁:

1.改进的攻击算法有可能比“通用数域筛法”更快的从公钥中规复出私钥。
对椭圆曲线密码系统编制没有效果。

2.量子打算机,这货太强大,连椭圆曲线密码系统编制都能破。

目前认为,一个老练的攻击者,有可能在短短几个月的韶光里破解出1024位RSA,但是2048bit RSA仍旧是安全的,然而,如果有一种方法能打破2048位RSA,那么这种方法对4096位RSA可能也有效。

如果你打算在2016年将加密技能运用到一个新的运用程序中,有可能打破RSA的那些迫不及待眉睫的威胁(真正的问题是,这种打破方法对ECDH或ECDSA是不是适用)绝对该当被考虑。
实际上,在未来,你最好考虑不要用RSA、DSA、或者传统的Diffie-Hellman算法。

总结

如果你须要在你的PHP运用中添加公钥加密算法:

1.不要用RSA。
我们乃至没有讲到数字署名,它同样也面临着很多尚未办理的繁芜问题(细微的假造攻击,假冒安全证明等等)。

2.你果你必须用RSA,不要直接用RSA。
最好利用稠浊的加密系统编制,结合RSA和下面的一个:

AES-256-GCM

AES-256-CTR + HMAC-SHA256 (in an Encrypt then MAC construction)

3.确保你用了OAEP,而不是PKCS1 V1.5添补。
否则,这肯定是一个漏洞。

同时,如果你对漏洞的详细内容感兴趣的话,你可以看一下下面的几篇文章:

“添补预言”攻击:

https://en.wikipedia.org/wiki/Padding_oracle_attack

为什么不要用PKCS1 v1.5添补方法:

https://cryptosense.com/why-pkcs1v1-5-encryption-should-be-put-out-of-our-misery/

Bleichenbacher’s CRYPTO 98 paper revealed a chosen ciphertext attack:

ftp://ftp.rsa.com/pub/pdfs/bulletn7.pdf

CVE-2016-1494 (python – rsa)数字署名漏洞详解:

http://www.freebuf.com/articles/terminal/101200.html

CVE-2016-1494 (python – rsa)英文数字署名漏洞详解:

https://blog.filippo.io/bleichenbacher-06-signature-forgery-in-python-rsa/