leeweir / Blog

通过issue写博客
http://leeweir.github.io/
The Unlicense
3 stars 0 forks source link

https优化 #4

Open leeweir opened 7 years ago

leeweir commented 7 years ago
  1. 加密算法优化 EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES,均采用前向安全性的强算法 目前携程使用的是RSA证书,优先采用ECDHE密钥交换,RSA签名,对称算法优先使用AES  优化依据: 目前业界主流的密钥交换+签名有三种选择: 1) RSA密钥交换(无需签名) 2) ECDHE密钥交换、RSA签名 3) ECDHE密钥交换、ECDSA签名 由于256位ECC Key在安全性上等同于3072位RSA Key,加上ECC运算速度更快,在同等安全条件下,ECC算法所需的Key更短,ECC证书文件体积也比RSA证书小1/3左右,从效率看,ECDHE密钥交换+ECDSA签名无疑是最好的选择。但是,ECC证书的浏览器兼容性要差一些,在90%左右。 再加上ECDHE支持perfect forward secrecy ,能够实现false start,所以,综合安全和性能的最优cipher suite配置是: ECDHE-RSA-AES128-GCM-SHA256,它被配置在服务端cipher suite的第一个,在客户端浏览器支持的的情况下,以服务端配置的顺序优先。  ToDo: 在Nginx V1.11.0 (当前线上为v1.6.2)开始提供对RSA/ECC双证书的支持,根据在TSL握手协商得到的Cipher Suite ,如果支持ECDSA就返回ECC证书,否则返回RSA证书。在线上Tengine升级到最新Nginx后,我们可以使用ECC证书来提高体验,并保证兼容性。

  2. 证书链优化 一条完整的证书链包含根证书—中间证书—站点证书,TLS的身份认证是通过证书链完成的,浏览器从站点证书开始递归校验父证书,直至出现信任的根证书。完整的证书链大小在4K左右,证书是在TLS握手期间传送,由于TCP初始拥塞窗口的存在,如果证书太长可能会增加TCP连接发送数据的次数,产生额外的往返开销,在弱网环境下延迟会增加得很明显。配置证书链的最佳实践是只包含站点证书和中间证书,服务端只需要发送两个证书,证书链大小控制在3Kb以内,以减少TLS握手时证书传输时间。

  3. False start TLS False Start指客户端在发送Change Cipher Spec Finished 同时发送应用数据,服务端在 TLS 握手完成时直接返回应用数据。这样,应用数据的发送实际上并未等到握手全部完成。在启用False Start之后,TLS阶段只需要 一次RTT就可以开始传输应用数据,相当于客户端提前发送应用层数据,无需等待服务端的确认。在服务端满足NPN和forward secrecy的条件下,大部分浏览器都会默认启用。

 优化后: 如下,在浏览器发送change cipher spec(315)之后,没有等待服务器的确认就立即发送了应用数据(316-319),相比没有启用的情况,可以优化50%的TLS握手时间

  1. Session Resumption Session Resumption是一种简化TLS握手的方法, 相比完全握手会少一个RTT的传输时间。Session Resumption的原理是将第一次TLS握手得到的对称密钥保存起来,在后续TLS握手时直接使用,以节省证书传送等开销。 目前生产环境SLB已经启用了Session Identifier和Session Ticket这两种Session Resumption方式。  Session Identifier Session Identifier是 TLS 握手中生成的 Session ID。服务端将 Session ID 协商后的信息存起来,浏览器也可以保存 Session ID,并在后续的 ClientHello 握手中带上它,如果服务端能找到与之匹配的信息,就可以完成一次简化握手。 但是在集群环境下,相同client发起的请求会被round robin到各台SLB服务器,在不具备分布式session cache的场景下,单一用户的再次请求很难命中相同的SLB服务器,无法进行简化握手。  Session Ticket Session Ticket 是用只有服务端知道的安全密钥加密过的会话信息,最终保存在浏览器端。浏览器如果在 下次ClientHello 时带上了 Session Ticket,只要服务器能成功解密就可以完成简化握手。 但是,Session Ticket需要浏览器支持,目前浏览器端的支持率约50%,在移动端的支持率更低。

 Todo: 在完成Tengine 升级到Nginx的改造后,启动Nginx对分布式Session Cache的支持,在Session Identifier的基础上 实现Session Cache的多机共享机制,提高Session Identifier命中率,提高简化握手的比率。

  1. OCSP Stapling OCSP Stapling是指服务端在证书链中包含颁发机构对证书的 OCSP 查询结果,从而让客户端的浏览器跳过本地发起验证的过程。服务端通常有更快的网络,获取 OCSP 响应更容易,也可以将 OCSP 响应缓存起来。OCSP 响应本身经过了数字签名,无法伪造,所以 OCSP Stapling 技术既提高了握手效率,也不会影响安全性。由客户端发起的OCSP验证大约需要500ms,而由服务器端开启验证+响应缓存后,可以在TLS握手阶段,将OCSP响应和证书链一起下发给客户端浏览器,节省客户端在线验证的开销。  Todo: 6月在生产环境开启OCSP Stapling

  2. TLS Record Size 服务器在建立TLS连接时,会为每个连接分配Buffer,这个Buffer叫TLS Record Size。Size值如果过大, 单个Record在TCP层会被分成多个包发送,必须等待这些包全部送到后才能解密,一旦出现丢包、拥塞、重传,握手延时将相应增加。而过小的TLS Record Size降低用户响应延时却降低了网络吞吐和利用率,所以需要合理设置TLS Record Size的大小。 由于TLS Record Size要大于证书链和OCSP Stapling响应大小,证书链不会分成多个record;同时要小于初始拥塞窗口值,保证服务器在通信之初可以发送足够数据而不需要等待浏览器确认。 Nginx默认的ssl_buffer_size为16k。根据携程实际的证书链大小,目前调整为6K。