3.2 HTTPS 对性能的影响

HTTPS为什么会严重降低性能?主要是握手阶段时的大数运算。其中最消耗性能的又是密钥交换时的私钥解密阶段(函数是rsa_private_decryption)。这个阶段的性能消耗占整个SSL握手性能消耗的95%。

前面提及了openssl密钥交换使用的算法只有四种:rsa, dhe, ecdhe,dh。dh由于安全问题目前使用得非常少,所以这里可以比较下前面三种密钥交换算法的性能,具体的数据如下: 

完成1000次握手需要的时间

上图数据是指完成1000次握手需要的时间,显然时间数值越大表示性能越低。图片和测试方法都可以参考原文,地址如下: http://vincent.bernat.im/en/blog/2011-ssl-perfect-forward-secrecy.html 。

密钥交换步骤是SSL完全握手过程中无法绕过的一个阶段。我们只能采取如下措施:

● 通过session cache和session ticket提升session reuse率,减少完全握手(full handshake)次数,提升简化握手(abbreviated handshake)率。

● 出于前向加密和false start的考虑,我们优先配置ecdhe用于密钥交换,但是性能不足的情况下可以将rsa配置成密钥交换算法,提升性能。

openssl 自带的工具可以计算出对称加密、数字签名及HASH函数的各个性能,所以详细数据我就不再列举,读者可以自行测试 。

结论就是对称加密RC4的性能最快,但是RC4本身不安全,所以还是正常情况下还是采用AES。HASH函数MD5和SHA1差不多。数字签名是ecdsa算法最快,但是支持率不高。

事实上由于密钥交换在整个握手过程中消耗性能占了95%,而对称加解密的性能消耗不到0.1%,所以server端对称加密的优化收益不大。相反,由于客户端特别是移动端的CPU计算能力本来就比较弱,所以对称加密和数字签名的优化主要是针对移动客户端。

poly1350 是google推出的号称优于aes-gcm的对称加密算法,适用于移动端,可以试用一下。

最后经过测试,综合安全和性能的最优cipher suite配置是: ECDHE-RSA-AES128-GCM-SHA256.

如果性能出现大幅度下降,可以修改配置,提升性能但是弱化了安全性,配置是:rc4-md5,根据openssl的规则,密钥交换和数字签名默认都是使用rsa。

4,HTTPS的支持率分析

分析了百度服务器端一百万的无线访问日志(主要为手机和平板电脑的浏览器),得出协议和握手时间的关系如下:

协议和握手时间的关系

从上表可以发现,ssl3.0速度最慢,不过支持率非常低。tls 1.0支持率最广泛。

加密套件和握手时间的关系如下:

协议和握手时间的关系

显然DHE对速度的影响比较大,ECDHE的性能确实要好出很多,而AES128-GCM对速度也有一点提升。

通过tcpdump分析client hello请求,发现有56.53%的请求发送了session id。也就意味着这些请求都能通过session cache得到复用。其他的一些扩展属性支持率如下:

加密套件和握手时间的关系如下:

这几个扩展都非常有意义,解释如下:

server_name,,即 sni (server name indicator),有77%的请求会在client hello里面携带想要访问的域名,允许服务端使用一个IP支持多个域名。

next_protocol_negotiation,即NPN,意味着有40.54%的客户端支持spdy.

session_tickets只有38.6%的支持率,比较低。这也是我们为什么会修改nginx主干代码实现session cache多机共享机制的原因。

elliptic_curves即是之前介绍的ECC(椭圆曲线系列算法),能够使用更小KEY长度实现DH同样级别的安全,极大提升运算性能。

5,结论

现在互联网上HTTPS的中文资料相对较少,同时由于HTTPS涉及到大量协议、密码学及PKI体系的知识,学习门槛相对较高。另外在具体的实践过程中还有很多坑和待持续改进的地方。希望本文对大家有一些帮助,同时由于我本人在很多地方掌握得也比较粗浅,一知半解,希望大家能多提意见,共同进步。

最后,为了防止流量劫持,保护用户隐私,大家都使用HTTPS吧,全网站支持。事实上,HTTPS并没有那么难用和可怕,只是你没有好好优化。


相关内容