第3章 TLS 1.3与TLS 1.2的区别
说实话,我刚接触TLS 1.3的时候,心里是有点抵触的。毕竟TLS 1.2用得好好的,改它干嘛?但等我真正去捋了一遍协议细节,才发现——嗯,这一版改动实在是太大了。大到什么程度呢?大到我建议你直接忘掉1.2的手绘脑图,重新画一张。
这一章我就带你逐个拆解,看看TLS 1.3到底比1.2强在哪。
握手流程:从2-RTT减到1-RTT
最直观的区别,就是握手次数。1.2需要两次完整往返(2-RTT)才能生成主密钥,而1.3只需要一次(1-RTT)。
| 阶段 | TLS 1.2 | TLS 1.3 |
|---|---|---|
| 初始握手 | 2-RTT(ClientHello + ServerHello + Certificate + ServerHelloDone → ClientKeyExchange + Finished → ServerFinished) | 1-RTT(ClientHello + ServerHello + EncryptedExtensions + Certificate + Finished) |
| 密钥交换 | 中间人协商后走ChangeCipherSpec | ServerHello后直接发送加密扩展 |
| 证书传输 | 明文传输 | 加密后再传(部分场景) |
我早期在做嵌入式SDK适配时,就被1.2那个又臭又长的握手流程折腾过。每次抓包都要看一堆ChangeCipherSpec,特别容易眼花。1.3把这些冗余全砍了——说白了,能提前算的密钥,在第一个Hello里就定下来。
一个小技巧:抓包时如果看到TLS 1.3的ClientHello里带了`key_share`扩展,那说明客户端已经在第一次消息里把秘钥协商参数传过去了。这也是握手能省掉一次往返的根本原因。
密码套件:从几十种砍到5种
1.2支持超过30种密码套件,什么AES-CBC、RC4、3DES……说实话,我见过不少老项目还在用RC4。但1.3做了个大手术:只允许AEAD加密算法。
- TLS 1.2时代:密码套件名长到让人崩溃(比如
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) - TLS 1.3时代:就5种,全部强制AEAD + 完美前向安全
| TLS 1.3 官方密码套件 | 说明 |
|---|---|
TLS_AES_128_GCM_SHA256 | 最常用,性能好 |
TLS_AES_256_GCM_SHA384 | 更高安全级别 |
TLS_CHACHA20_POLY1305_SHA256 | 移动端、无AES硬件加速时推荐 |
TLS_AES_128_CCM_SHA256 | IoT场景优化 |
TLS_AES_128_CCM_8_SHA256 | 短标签模式(不推荐日常使用) |
我当时在验证一个SDK版本时,就因为1.3的密码套件列表长得太整齐而怀疑人生——真的只有5个?后来翻RFC发现确实如此。这种"少即是多"的设计,让配置和管理变得简单太多。
重要原则:TLS 1.3不再支持密钥传输协议(RSA-KEM),所有密钥交换都必须使用ECDHE或DHE。这意味着服务器无法提前知道客户端的公钥——也正因为这个改动,前向安全性才得以保证。
向前安全性:从"可选"变成"必须"
你想想看,如果一个攻击者今天把你的会话流量全部录下来,等过几年你私钥泄露了,还能不能解密这些流量?在TLS 1.2里,如果用了静态RSA密钥交换(也就是常见的 TLS_RSA_WITH_AES_128_CBC_SHA),那肯定能。但1.3彻底禁用了这种模式。
我记得有一次做客户代码审计,对方还在用 TLS_RSA_WITH_AES_256_CBC_SHA。我跟他说,你这个连接虽然用了强加密,但只要私钥一泄露,历史的会话都会被翻出来。他当时脸色就变了。所以向前安全(PFS)在1.3里是强制的,所有密钥交换都基于临时密钥对。
会话恢复:0-RTT的新玩法
1.2也有会话恢复——通过Session ID或Session Ticket。但1.3引入了一个更激进的东西:PSK(预共享密钥)+ 0-RTT。什么意思?就是第一次握手之后,客户端可以缓存一个密钥,下次再连的时候,直接在第一个消息里带上加密数据。
注意:0-RTT有重放攻击风险。我在一个支付SDK里就踩过坑——客户端用0-RTT重发了扣款请求,服务器没做去重,导致用户被重复扣款。后来我们强制对幂等性敏感的操作走完整1-RTT握手。
不过话说回来,在大多数Web场景下(比如API调用、实时通信),0-RTT能带来明显的延迟改善。如果你在适配SDK时发现某些场景握手时间特别长,不妨看看是不是会话票证没存好。
移除的安全隐患
1.3不光做了加法,还做了大量减法。下面是我列出来的几个被剔除的"经典坑":
- 压缩功能:CRIME攻击的温床,直接移除
- 静态RSA密钥交换:不提供前向安全,砍掉
- ChangeCipherSpec:过去很多降级攻击都靠这个协议字段作妖
- 不安全的哈希:MD5、SHA-1在证书签名里还能用,但在握手MAC中被禁用
- ECCP曲线:只保留P-256、P-384、P-521、X25519、X448(去掉了P-224、secp256k1等)
我曾经在解析1.2的ChangeCipherSpec时,因为时序问题搞错过一次——服务端发了两次CCS,客户端直接崩溃。1.3虽然还保留了这个消息的兼容形态,但实际流程里已经完全用不到了。
一张图看懂区别
核心差异总结:TLS 1.3 把原本需要两次往返的消息合并成一次,同时把所有不安全的内容全部切除。适配SDK时,你只需要关注密码套件列表、会话票证缓存、以及是否启用0-RTT这三点。