这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战
上回书说到TLS1.2的流程和报文,目前TLS1.2仍是主流,但越来越多的网站已经开始采用TLS1.3。 本文包含1.3与1.2的对比汇总,1.3信令流程详细说明,以及1.3中的密钥算法
1.3 VS 1.2
我们首先来看一下TLS1.3对比1.2的几个重大的改变:
-
1.3版大幅缩减了握手交互流程,缩短连接建立时延
-
1.3版禁止了版本重协商(renegotiate), 防止黑客通过重协商降低安全等级,同样如果已经建立了TLS1.2的连接,那么也不能重协商到TLS1.3,下图是从rfc8446截取的:
- 1.3版移除了一些1.2版中不再安全的加密算法,比如RSA,而且在密钥协商时,只保留了AEAD类加密算法:
-
1.3版将更多信令进行了加密,包括证书信息等,而不是像1.2版中很多信令都是明文传输,我会在下文中详细对比。
-
1.3版引入了一种新的密钥协商机制——PSK(pre-shared-key)预分享密钥, 这是与1.2版本类似的会话恢复机制(session resumption),并基于此实现了0-RTT(Round Trip time) 数据发送,即在client hello中携带应用数据信息,如下图所示:
TLS1.3信令流程
相比于TLS1.2来说,1.3版本的握手信令肉眼可见的精简。下图是我从wireshark中截取的实际信令,无论从消息数量,还是从size上来说都少了:
我们来详细看一下报文里的内容。
Client Hello
- 目前主流浏览器都已经支持TLS1.3,所以无论服务器的TLS版本是什么,客户端发送的这条hello信息都是一样的。
- 虽然在这条消息中,version字段仍然是1.2,这主要是考虑兼容性的问题,实际上是将选择权交给服务器,在supported_version字段中,客户端写明了也支持TLS1.3
- 重点讲一下key_share: 客户端在client hello中直接就分享了自己的密钥协商参数,让服务器计算handshake-master_key,这样做的目的是减少了1.2版本中server/client key exchange信令
- 这个key每个会话都不一样,一个会话中每次生成也不一样;Group必须是supported_groups中的值
- 这样做的前提是:客户端假设服务器会选择与它一样的密钥交换参数组,如上例中的“x25519",如果服务器选择了其他参数组,则服务器会发送"hello retry request"给客户端,重新协商密钥;
- 还需要关注psk_key_exhange_modes,PSK(Pre-shared-key)预分享密钥是TLS1.3新引进的特性,这里是表明它的工作模式,它是在通信双方通过ECDHE交换密钥后,再生成的。
Server Hello
TLS1.3对这条消息进行了很大修改,报文如下:
-
version: 这个版本写的虽然是1.2,目的是向前兼容,因为HTTPS是hop by hop的,允许中介网元转发,所以为了防止有些中介网元版本不符,保留了该字段内容,实际的协议版本是最底部extension:supported_versions
-
Random: 服务器随机码,用于生成handshake-master key
-
Session ID: 依然为了向前兼容,在TLS1.3版中,这个字段只是client hello中session id的回显,没有其他意义
-
Cipher Suite: 服务器选择的密码组,TLS_CHACHA20_POLY1305_SHA256,删掉了密钥交换和身份验证算法部分,只保留了最终的对称加密算法
-
key_share: 会优先选择与client key_share一样的group,并直接发送计算出来的公钥,供客户端计算handshake-master key. - 这样做的目的是减少了1.2版本中server/client key exchange信令
到这里,双方的密钥协商就完成了,各自都可以生成handshake_master_key,并由此生成对称的session key.
Change Cipher Spec
最后服务器与客户端都发送这条消息给对方,指示开始进行加密传输
身份验证在哪里?
可以看到,TLS1.3压缩了密钥交换的部分,但是防止中间人攻击的身份验证呢?
上图是RFC8446官方提供的流程图,可以看到1.3是在完成密钥协商后,才发送certificate,并且用server_handshake_traffic_key进行了加密,这也是1.3版中新引入的特性,增强了安全性。
TLS1.3版中的key 与 HKDF算法
最后再补充一点,在1.3版中密钥生成部分做了比较大的改变,没有了PRF算法,取而代之HKDF算法(HMAC-based Extract-and-Expand Key Derivation Function)
-
HKDF的主要目的使用原始的密钥素材(key material),派生出一个或更多个能达到安全要求的密钥,同时需要保证新密钥的随机性。
-
HKDF包含两个基本使用步骤:提取 Extract, 扩展Expand。
-
提取:从密钥素材里派生出一个符合安全要求的伪随机密钥。
-
扩展:使用提取出来的伪随机密钥,扩展出指定长度的密钥,同时保证随机性。
下图是在整个TLS1.3的密钥生成的步骤,可以看到HKDF算法发挥了重要作用
-
结合上图,可以看到client发送0-RTT的密钥是从PSK中衍生来的.
-
握手期间的Server 给 Client 发送的消息用 server_handshake_traffic_secret,Client 给 Server 发消息用的client_handshake_traffic_secret都是通过 HKDF 算法从PreMasterSecret 和 Early Secret 密钥衍生出来的.
-
通过 Handshake Secret 密钥导出主密钥 Master Secret,最后从Master secret中再次通过HKDF导出数传用的server_application_traffic_secret_N与client_application_traffic_secret_N.
-
resumption_master_secret用来生成PSK,在New Session Ticket消息中发给客户端。
以上!
感谢阅读,如有不准确和错误之处请留言指正,我会立即修正,感谢!
总结不易,请勿私自转载,否则别怪老大爷不客气
欢迎喜欢技术的小伙伴和我交流,微信1296386616
参考资料:
《SSL/TLS、对称加密和非对称加密和TLSv1.3》 tinychen zhuanlan.zhihu.com/p/345943705
《The Transport Layer Security (TLS) Protocol Version 1.3》 IETF datatracker.ietf.org/doc/html/rf…
《TLS 1.3: Everything you need to know》 by Patrick Nohe www.thesslstore.com/blog/tls-1-…
《A walkthrough of a TLS 1.3 handshake》 by Joshua Davies commandlinefanatic.com/cgi-bin/sho…
《HKDF算法》 suntus suntus.github.io/2019/05/09/…
<<HTTPS 温故知新(五) —— TLS 中的密钥计算>> Halfrost halfrost.com/https-key-c…