摘要: HTTPS 时代已经来临,TLSv1.3 已经标准化,未来各大浏览器会逐渐支持 TLSv1.3,本主题将分享 TLSv1.3 核心原理,以及如何结合 Tengine 让 HTTPS 更快、更安全。
TLSv1.3 概述
背景
SSL 是1994年网景公司提出,主要解决安全传输从0到1的过程,真正被大规模应用是1996年发布的 SSLv3,经过了几年的发展,在1999年被IETF纳入标准化,改名叫 TLS,其实本质是一样的,TLSv1.0 跟 SSLv3 没有太多差异,TLSv1.1 做了一些 bug 修复和支持更多的参数,TLSv1.2 基于 TLSv1.1 做了更多的扩展和算法上改进,从2008年到今年近10年的时间,TLSv1.3 在今年3月份被 IETF 讨论组评正式纳入标准化,8月初出了 RFC8446,但是 TLSv1.3 在2014年已经被提出来了,经历了4年时间的讨论和优化,但是因为 TLSv1.2 已经被大量应用,一些网络设备并不兼容之前提出的TLSv1.3草案,所以后来做了很多次优化,在第28个草案时才确定没有问题,正式纳入标准化。
趋势
TLS 最大的应用就是 HTTPS,我们来看看 chrome 统计的 HTTPS 网页趋势,2015年的时候,大多数国家的HTTPS网页加载次数只占了不到 50%,2016年美国这个占比到了将近 60%,去年就已经超过70%, 目前美国的统计数据是 85%,可见,离 100% 已经很近了,从图上可以看出,日本目前接近 70%,这里面没有统计到中国的数据,我估计也就 40% 左右,落后其他国家三年左右时间,空间还有很大,而且未来HTTPS趋势是非常明显的。至于国内大多数用户不愿意使用HTTPS的原因,无非几个:安全意识、技术难度、性能和用户体验、成本等等原因,这方面阿里云 CDN 也在努力帮助用户解决这些技术问题,在这里不就展开了。
握手原理
TLSv1.2 握手原理
完成握手
先来看看 TLSv1.2 的完整握手流程:
SSL 握手之前是 TCP 握手,这里面没画出来,SSL 握手总是以 ClientHello 消息开始,就跟 TCP 握手总是以 SYN 包开始一样。
整个握手过程分为两个过程:
- 参数协商
主要通过 Client Hello 和 Server Hello消息来协商,Client Hello 提供客户端支持的参数(比如:密钥套件、签名算法、应用层协议列表等等),另外还包含一些必要的参数(比如:客户端随机数、SNI、session id 等等),服务器从中选取自己支持的参数,然后在 Server Hello 消息中返回,告知客户端本次会话要使用哪些参数。 - 密钥交换
主要通过 Server Key Exchange 和 Client Key Exchange 来交换,其中 Server Key Exchange 是用来发送服务器椭圆曲线算法的参数、公钥信息以及该信息的签名,Client Key Exchange 用来发送客户端椭圆曲线算法的公钥信息,双方得到对方椭圆曲线算法公钥之后,与自己本地生成的临时私钥,通过椭圆曲线算法生成预主密钥,再导出主密钥和会话密钥,握手完成之后通过会话密钥来加密通信。
可以看出,完整的握手需要2个 RTT,而且每次握手都用到了非对称加密算法签名或者解密的操作,比较耗时和耗 CPU。假如1个 RTT 需要 100ms 的话,TLSv1.2 的完整握手时间就需要 200ms,再加上 HTTP 请求时间,那首字节时间就是 300ms 左右了。
SSL 的握手消息虽然比较多,但很多消息都是放在一个 TCP 包中发送的,从抓包可以看出完整的 SSL 握手需要2个 RTT。
会话恢复
刚才通过完整的 SSL 握手可以看出几个缺点:
- 2个 RTT,首包时间较长
- 每次都要做非对称加密运算,比较耗 CPU,影响性能
- 每次都要传证书,证书一般都比较大,浪费带宽
SSL 握手的目的是协商参数和会话密钥,如果能把这些会话参数缓存起来那就可以没有必要每次都传