互联网上前一百万个网站的 SSL/TLS 分析
目前看来评估不同的SSL/TLS配置已经逐渐成为了我的业余爱好。在10月份发表了Server Side TLS之后,我参与一些讨论密码性能、key的长短、椭圆曲线的安全等问题的次数都明显增多了(比较讽刺的是,当初之所以写“Server Side TLS”就是非常天真的希望减少我在这个话题上的讨论次数)。
SSL/TLS服务器端的配置教程如今越来越多。其中很快就得到关注的一篇是Better Crypto,我们曾经也在dev-tech-crpto邮件列表中讨论了多次。
人们总是对这些话题非常有热情(我也不例外)。但是有一个问题我们一直念念不忘,就是总想着尽快干掉那些被弃用的密码,即便这意味着切断了与一些用户的连接。我是绝对反对这样做的,并且始终坚信最好的做法是为所有用户都维持向后兼容性,即使是以在我们的TLS服务器上保留RC4、3DES或是1024DHE key为代价。
最近在dev-tech-crypto上有这样一个问题:“我们是否可以在Firefox上将RC4完全移除?”。有人可能认为,因为Firefox支持所有其他的密码(AES, AES-GCM, 3DES, Camelia…),我们当然可以在不影响用户的前提下移除RC4。但是我们没有实际的数据来证明这一点,所以也不能随便作出这样的决定。
接收挑战:我将带上我的武器cipherscan出来兜兜风,并打算扫描下互联网。
扫描方法
扫描脚本在github上,数据结果在这里。未压缩的数据有1.2GB之大,但是XZ难以置信的将其压缩成了一个只有17MB大小的数据存档。
我使用Alexa所列出的前1,000,000个网站作为数据源。使用“testtop1m.sh”脚本并行扫描目标,并通过节流来限制同时扫描的数量(设置为100),然后将结果写入到“results”目录。每个扫描目标的结果被存放在一个json文件中。另一个脚本名为“parse_results.py”,它会扫一遍“results”目录并计算统计数据。非常基础的东东。
我花了大概36个小时来运行整个扫描流程。发现总共有451470个网站开启了TLS,占总数的45%。
虽然这不是一个全面的统计,但这一数据足以让我们评价SSL/TLS在现实世界中的状态。
对这451470个网站的SSL/TLS调查
密码
Cipherscan返回了每个目标服务器上所有支持的密码。下表显示了普遍被支持的密码以及仅被一些网站所支持的密码。最后一项最有趣,似乎1.23%的网站仅接受3DES,而1.56%的网站仅接受RC4。这对于那些正考虑放弃支持3DES和RC4的开发者来说是非常重要的数据。
值得注意的是:有两个人不知出于什么原因仅仅只在他们的网站上开启了Camellia。好吧先生们,我为你们举杯。
对于那些不寻常的密码,我为其添加了前缀“z”并放在列表底部,非常的显眼。事实上从28%的网站明确支持DES-CBC-SHA这一点上可以看出更好的TLS文档和培训的必要性。
Supported Ciphers Count Percent -------------------------+---------+------- 3DES 422845 93.6596 3DES Only 5554 1.2302 AES 411990 91.2552 AES Only 404 0.0895 CAMELLIA 170600 37.7877 CAMELLIA Only 2 0.0004 RC4 403683 89.4152 RC4 Only 7042 1.5598 z:ADH-DES-CBC-SHA 918 0.2033 z:ADH-SEED-SHA 633 0.1402 z:AECDH-NULL-SHA 3 0.0007 z:DES-CBC-MD5 55824 12.3649 z:DES-CBC-SHA 125630 27.8269 z:DHE-DSS-SEED-SHA 1 0.0002 z:DHE-RSA-SEED-SHA 77930 17.2614 z:ECDHE-RSA-NULL-SHA 3 0.0007 z:EDH-DSS-DES-CBC-SHA 11 0.0024 z:EDH-RSA-DES-CBC-SHA 118684 26.2883 z:EXP-ADH-DES-CBC-SHA 611 0.1353 z:EXP-DES-CBC-SHA 98680 21.8575 z:EXP-EDH-DSS-DES-CBC-SHA 11 0.0024 z:EXP-EDH-RSA-DES-CBC-SHA 87490 19.3789 z:EXP-RC2-CBC-MD5 105780 23.4301 z:IDEA-CBC-MD5 7300 1.6169 z:IDEA-CBC-SHA 53981 11.9567 z:NULL-MD5 379 0.0839 z:NULL-SHA 377 0.0835 z:NULL-SHA256 9 0.002 z:RC2-CBC-MD5 63510 14.0674 z:SEED-SHA 93993 20.8193
密匙协商
让人惊喜的是部署了ECDHE的比例。21%虽然不算是一场胜利,但是对于其被视为一种非常有希望在不久的将来取代RSA(至少是在密匙协商方面)的算法来说,这却是一个鼓舞人心的数字。
DHE,从SSLv3开始支持到现在已经有接近60%的部署量。我们需要尽快将这个数字提升到100%!
Supported Handshakes Count Percent -------------------------+---------+------- DHE 267507 59.2524 ECDHE 97570 21.6116
PFS
完全正向保密(perfect forward secrecy)目前非常流行,所以评估它的部署量最有趣。事实上我重复检查了3次结果才确定下表所示的比例,75%的网站支持PFS,非常准确,因为对我来讲这是非常大的数量。更令人惊讶的是,事实上61%被测试的网站,要么是自己倾向、要么是让客户端倾向于PFS key交换(DES或ECDHE)而不是其它密码。
不出所料,绝大多数——98%的DHE key是1024位。导致这个情况的原因如下:
在Apache2.4.6及其以前的版本中,DH参数总是设置为1024位并且不是用户所能配置的。未来Apache的版本会为DH参数自动选择一个更好的值。
java6,或许还有一些其它的库,并不支持大于1024位的DHE key。
所以,虽然大家都同意需要一个2048位的RSA算法模型,但使用1024位的DHE key,即便其有效的降低了TLS的安全性,可目前还没有任何的解决办法——不同于打破旧客户端的向后兼容性。
在ECDHE这方面,总是使用P-256曲线来完成握手。同样的,这也很容易理解,因为IE、CHrome、Firefox目前仅仅持P256。但是根据最近由DJB和Lange发表的研究显示,这可能不是最安全的选择。
下表中的曲线统计存在一些瑕疵:Cipherscan在底层使用OpenSSL,而我并不确定OpenSSL是如何在握手阶段选择曲线的。这是Cipherscan需要改进的一块,所以希望大家不要受这些数字的影响。
Supported PFS Count Percent PFS Percent -------------------------+---------+--------+----------- Support PFS 342725 75.9131 Prefer PFS 279430 61.8934 DH,1024bits 262561 58.1569 98.1511 DH,1539bits 1 0.0002 0.0004 DH,2048bits 3899 0.8636 1.4575 DH,3072bits 2 0.0004 0.0007 DH,3248bits 2 0.0004 0.0007 DH,4096bits 144 0.0319 0.0538 DH,512bits 76 0.0168 0.0284 DH,768bits 825 0.1827 0.3084 ECDH,P-256,256bits 96738 21.4273 99.1473 ECDH,B-163,163bits 37 0.0082 0.0379 ECDH,B-233,233bits 295 0.0653 0.3023 ECDH,B-283,282bits 1 0.0002 0.001 ECDH,B-571,570bits 329 0.0729 0.3372 ECDH,P-224,224bits 4 0.0009 0.0041 ECDH,P-384,384bits 108 0.0239 0.1107 ECDH,P-521,521bits 118 0.0261 0.1209
协议
在协议扫描的结果中有些地方让我很吃惊:仍然有18.7%的网站支持SSLv2!拜托,各位,我们已经重复了这个问题有很多年了:SSLv2漏洞太多了,不要使用它!
我非常欣赏这38个仅仅接受SSLv2的网站。干的好。
同样有趣的是,2.6%的网站支持TLSv1.2,而不是TLS1.1。合理的情况下,TLSv1.2网站的数量应该大于2.6%才对,但事实并非如此(只有0.001%).所以我只能想象,出于某些原因,网站都使用TLSv1和TLSv1.2,而不是1.1。
更新:HN上的“harshreality”找出了一条OpenSSL中的更新日志可以来解释这种行为:
Changes between 1.0.1a and 1.0.1b <a title="26 Apr 2012" href="https://jve.linuxwall.info/blog/26%20Apr%202012">26 Apr 2012</a> - OpenSSL 1.0.0 sets SSL_OP_ALL to 0x80000FFFL and OpenSSL 1.0.1 and 1.0.1a set SSL_OP_NO_TLSv1_1 to 0x00000400L which would unfortunately mean any application compiled against OpenSSL 1.0.0 headers setting SSL_OP_ALL would also set SSL_OP_NO_TLSv1_1, unintentionally disablng TLS 1.1 also. Fix this by changing the value of SSL_OP_NO_TLSv1_1 to 0x10000000L Any application which was previously compiled against OpenSSL 1.0.1 or 1.0.1a headers and which cares about SSL_OP_NO_TLSv1_1 will need to be recompiled as a result.
不出所料,绝大多数网站都支持SSLv3和TLSv1,分别为99.6%和98.7%。有少量的网站支持TLS1.1和1.2,这令人担忧,但一点也不奇怪。
考虑到近期的商业产品对TLS版本的可怜的支持,所以这也不能怪系统管理员。供应商可以肯定会推动这一进程,所以在你更新下一个合同前,确保将TLSv1.2加入你的心愿单。
Supported Protocols Count Percent -------------------------+---------+------- SSL2 85447 18.9264 SSL2 Only 38 0.0084 SSL3 449864 99.6443 SSL3 Only 4443 0.9841 TLS1 446575 98.9158 TLS1 Only 736 0.163 TLS1.1 145266 32.1762 TLS1.1 Only 1 0.0002 TLS1.2 149921 33.2073 TLS1.2 Only 5 0.0011 TLS1.2 but not 1.1 11888 2.6332
哪些没有被测试?
这不是一个全面的测试。还有RSA key的大小没有被评估。同时还有TLS扩展,OCSP Stapling支持,以及一些值得反复观察的有趣的特征。下次再说吧。
培训,以及向后兼容
如果要说这个小实验说明了些什么问题,那就是旧的密码和协议还远远没有被抛弃。当然,如今你可以决定在客户端上干掉RC4和3DES,但是要注意有一小部分的因特网将是你和你的用户连接不到的。
对这个情况我们可以做什么?培训是关键:TLS是一个复杂的专题,而大多数的管理员和网站所有者没有时间和知识去找遍几十个邮件列表和博客来得到最好的配置选择。
这也是编写Server Side TLS和Better Crypto等文档的首要动机。我们中的一些人是致力于改进这些文档的。但是我们需要一个团队来传播这些信息,在会议、邮件列表和用户群中指导管理员们,同时推动网站所有者为他们的网站添加更多的安全配置。我们需要一些帮助:去那里!教TLS吧!
原文链接: Julien Vehent 翻译: 伯乐在线 - deathmonkey
译文链接: http://blog.jobbole.com/55550/