“do it, do it work, do it better … and secure ☠️”

随着追逐利益而来的恶意参与者越来越多,当前的 Web 应用,已经从野蛮生长转而越来越多地关注安全 —— 通信安全、数据安全、用户安全、企业安全,甚至国家安全。作为通过网络传输数据的应用,最简单的获取安全的方式是采用 TLS。

TLS(Transport Layer Security),即传输层安全,TLS 直接构建在传输层之上,一般基于 TCP,也可以基于 UDP(如 DTLS)。TLS 负责将待传输的数据加密,加密后传输过程中任何中间方都再看不到具体内容,保障了安全性。关于 TLS 的更多内容可参见另一篇博文 简单解释TLS,本篇不再赘述。

我们的关注点重新集中到性能上,任何的引入必然导致额外的开销,对于 Web 应用来说,最要命的开销就是延迟。那么可以从哪些方面着手优化延迟?

会话复用

在上一篇关于 TCP 的讨论中,我们知道每次 tcp 连接的建立都需要经过三次握手,产生至少一个 RTT(Round-Trip Time) 的延迟,现在引入 tls,情况又如何?

对于建立在 tcp 之上的 tls,除了因为 tcp 三次握手引入的一个 RTT 延迟外,根据 tls 协议设计,TLS 会话的一次完整握手还会再引入 2 个 RTT 的延迟,所以一个 https 连接的初次建立过程会引入 3 个 RTT 延迟。

tcp 通过连接复用实现在需要的时候规避握手延迟,类似地,tls 也有会话复用机制——称为简短握手,可将 2 次 RTT 延迟减少到 1 次。

这是如何做到的呢?在建立会话时,服务器会创建一个 32 byte 的会话 id —— 会话 id 可以关联到该次会话协商出的一系列加密参数,然后通过 ServerHello 消息发送给客户端。在下一次通信时,客户端可以在发送的 ClientHello 消息中包含上一次的会话 id,如果服务器认可,则接下来就可以基于上一次会话的会话参数开始通信,从而省去 1 次 RTT。

在需要同时发起多个 https 连接时,可以重用第一个 tls 握手协商出来的会话参数。

一般服务器端可以将 tls 会话的有效时间设置为 1 天,对于高并发场景,可能导致会话缓存占用过多的内存资源,必须要设计好相应的缓存淘汰机制,或者采用会话记录单机制 —— 服务端使用密钥将会话相关的参数加密后发给客户端,由客户端保存,后续需要时客户端将加密信息发回服务端,服务端解密后使用。

TLS 记录

TLS 会将消息拆分为若干条 TLS 记录,每条记录上限为 16 KB。TLS 记录太小的话,在 tcp 分组中占比太小,浪费 tcp 分组;TLS 记录太大的话,会分拆为若干 tcp 分组,此时需要等待所有分组到达,才能解密出数据,引入额外延迟。


From optimizing-tls-record-size-and-buffering-latency

所以最好将 TLS 记录大小配置为恰好放入一个 tcp 分组,也可以配置为根据相关窗口大小动态调整记录大小。

证书验证

TLS 的安全是建立在 PKI 体系之上,在 PKI 体系中,由权威证书颁发机构给网站颁发身份证书,在 tls 握手过程中,服务器需要发送证书给客户端以验明正身。但证书这玩意,有生就有死,所以客户端在收到证书后,除了查看证书里签发时写入的静态信息是否确实可信,还要验证证书在当前时刻是否还有效。

这是一个典型的响应优先还是一致性优先的问题,方案不外乎两种:缓存 or 实时。

  • 缓存方案:证书颁发机构会维护一个已撤销证书列表,称为 CRL(Certificate Revocation List,证书撤销名单),服务器或者客户端可以缓存到本地使用。缓存的问题就是,有可能你刚刚缓存过一次,就有一个证书被撤销了,导致缓存与实际状态不一致。
  • 实时方案:鉴于缓存方案的问题,提供了互补的实时查询方案,称为 OCSP(在线证书状态协议),OCSP 的问题在于可能会阻塞 tls 协商过程,需要等待 OCSP 验证完成才能继续,特别是内网环境使用 IE + 自签名证书开发时容易被坑,博主就被坑过一次。如果访问不了证书颁发机构,且环境允许,可以考虑禁用 OCSP。

出于安全考虑,一般网站的证书不会直接使用根证书签发,而是使用(根证书签发出来的)中间证书签发,而根证书密钥则被离线存放。由于浏览器验证证书时,会顺着证书链验证每个节点的证书,所以这里有几个可以优化的点:

  • 服务端在发送时最好同时把中间证书也一并附上,避免浏览器再单独发起一次中间证书请求,引入额外的延迟;
  • 发送时无需包含根证书,因为已经存在客户端了;
  • 签发证书层次不要过多,最好就一层中间证书,否则发送证书链时,数据太多;
  • 非必要的证书就不要发了,避免传输数据过多,导致额外的分片,引入额外延迟;
  • OCSP stapling,由服务端来发起 OCSP 请求,并将请求响应放在给客户端的证书链中,需要浏览器支持。
  • 使用椭圆曲线证书链,比 RSA 证书链小,传输数据少一点;
  • 同一张证书不要绑定过多域名,传输数据少一点。

其他

ALPN(Application Layer Protocol Negotiation)

在 tls 握手过程中嵌入 ALPN 机制,协商上层使用的应用协议,不用等待 tls 建立后单独协商,减少延迟,整个过程就是在 ClientHello 中增加一个 ProtocolNameList 字段,服务器收到后在 ServerHello 回复中返回选中的协议。


参考

  • 《Web 性能权威指南》
  • 《HTTPS 权威指南》

原文地址:http://www.cnblogs.com/read-the-spring-and-autumn-annals-in-night/p/16910028.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性