2、TLS握手详解:TLS 1.2握手流程、TLS 1.3握手改进、密钥交换算法

聊到TLS审计,你对握手过程的熟悉程度直接决定了排查问题的效率。握手是TLS的核心。

说白了,握手就是客户端和服务器在正式传输数据前,互相确认身份、协商加密参数、生成对称密钥的过程。理解了握手,你才能真正看懂TLS配置哪里不对、哪里存在风险。

2.1 我惯用的握手排查思路:先画时间线

每次排查TLS问题,我个人习惯先画一条时间线。这样做不容易漏掉关键步骤。

TLS 1.2的握手,好理解,但也容易出问题。它有个特点:两次往返(2-RTT)。

核心概念:RTT(Round Trip Time)—— 客户端发一个包到服务器,服务器回一个包,这一来一回的时间。

2.2 TLS 1.2 握手流程:经典的五步走

TLS 1.2的完整握手,我习惯拆成五步记忆。我刚开始做审计时,就是靠这张图一步步对照抓包结果。

  1. ClientHello —— 客户端告诉服务器:“我支持这些TLS版本、密码套件、随机数。”
    嗯,这里要注意,版本号和加密套件列表很容易被伪造攻击篡改,审计时必须校验。
  2. ServerHello + Certificate + ServerHelloDone —— 服务器选择一套加密参数,发证书,然后说:“我说完了。”
    我曾经在项目中遇到过,服务器发来的证书和域名不匹配,导致握手直接失败。
  3. ClientKeyExchange + ChangeCipherSpec + Finished —— 客户端生成预备主密钥,用服务器的公钥加密后发过去。同时告诉服务器:“我准备就绪,以后用对称密钥通信。” 并发一个验证消息。
  4. ChangeCipherSpec + Finished —— 服务器也解密出预备主密钥,生成对称密钥,然后回一个验证消息:“我也准备好了。”
  5. 开始加密通信 —— 双方都确认对方身份和密钥无误,开始用对称加密传数据。

审计避坑点:TLS 1.2握手的第3步中,客户端密钥交换消息(ClientKeyExchange)直接影响最终会话密钥。如果审计时发现这一消息中的公钥长度不对,或随机数不随机,那基本可以断定存在安全风险。

2.3 TLS 1.3 握手改进:减到一次半往返

TLS 1.3最让我觉得过瘾的改进,就是把2-RTT砍成了1-RTT,甚至0-RTT。你想想看,这在延迟敏感的业务场景下有多重要。

  • 主要改进点:
    • 砍掉了不安全的密码套件,只保留AEAD算法。据说当年为了兼容老设备,不少团队吃过亏。我建议审计时,直接检查是否启用了TLS 1.3,并禁止其回退到TLS 1.2的低安全套件。
    • 把协商密钥的过程提前。客户端在第一个消息里,就发给你一个DH公钥。服务器收到后,直接回复自己的公钥和Finished验证。三次消息交换,握手完成。
    • 加密了部分握手消息。以前Certificate消息是明文的,现在加密了。谁发的证书、证书链条有没问题,在抓包工具里看不到,只能靠服务端日志来审计。

一条实用建议:审计时,如果发现客户端发送的TLS 1.3 ClientHello中携带的“key_share”扩展缺失,那基本上可以断定该连接会回退到TLS 1.2。这种降级行为需要重点记录。

2.4 密钥交换算法:DH与ECDHE的对比

密钥交换算法决定了如何安全地生成对称密钥。我碰到最多的情况是RSA和ECDHE的对比。

特性 RSA密钥交换 ECDHE密钥交换
是否支持前向安全性 否 是
密钥生成方式 客户端生成预备主密钥,用公钥加密 双方用椭圆曲线DH算法,各自算出相同密钥
性能 公钥加密性能差,私钥解密性能差 ECDH计算较快,且支持硬件加速
审计关注点 证书私钥一旦泄露,历史会话全部可解密 每次连接使用临时密钥,私钥泄露不影响历史会话
推荐程度(2025年) 不应使用 强推荐

这个表格我记得当年做SDLC审计时就反复用过。ECDHE的最大价值在于“前向安全性”。说白了就是:即使今天服务器私钥被偷,攻击者也解密不了昨天偷录的加密流量。

2.5 TLS 1.2 与 TLS 1.3 握手流程对比图

为了更清晰地展示两者的差异,我画了下面这张对比图。左边是TLS 1.2,右边是TLS 1.3。你一看就明白,TLS 1.3少了一次往返。

TLS 1.2 vs TLS 1.3 握手流程对比 TLS 1.2(2-RTT) ① ClientHello(版本+套件列表+随机数) ② ServerHello Certificate(明文) ServerHelloDone ③ ClientKeyExchange ChangeCipherSpec Finished ④ ChangeCipherSpec + Finished ⑤ 加密通信开始 TLS 1.3(1-RTT) ① ClientHello (协商版本+套件+DH公钥) ② ServerHello (DH公钥+证书+Finished) ③ 客户端计算对称密钥 ④ 加密通信开始 TLS 1.3握手消息也可加密(EncryptedExtensions),延迟更小,安全性更高

2.6 审计实战中的握手排查要点

光知道流程还不够,你得会用抓包工具去验证。我分享一下我的检查清单。

  • 检查ClientHello中的密码套件列表:看有没有过时的、不安全的套件。
  • 检查ServerHello中的套件选择:服务端是否强制使用了安全的套件,还是向下兼容了弱套件。
  • 检查Certificate消息:证书链是否完整,证书是否过期,证书签发者是否可信。
  • 检查签名算法和哈希函数:使用SHA-256还是SHA-1?SHA-1在2025年基本可以认为是不可信的。
  • 检查扩展域:比如Supported Groups、Signature Algorithms、Key Share等,确保服务器支持椭圆曲线,且优先使用安全的曲线(如x25519、secp384r1)。

一次实战案例:我曾经在审计某金融系统时,发现其TLS配置虽然启用了ECDHE,但使用了过时的secp256r1曲线。我建议升级到x25519,并移除对RSA密钥交换的支持。整改后,不仅安全评级提升,吞吐性能还提升了约5%。

2.7 一个简单的抓包验证思路

你可以用Wireshark或tcpdump做一次简单的验证。

# 示例(Linux/macOS):抓取到服务器443端口的TLS握手包,保存为文件
tcpdump -i any -w handshake.pcap host 192.168.1.100 and port 443

# 然后使用Wireshark打开,过滤 tls.handshake.type == 1 (ClientHello)
# 或 tls.handshake.type == 2 (ServerHello)

打开后,我建议你重点关注ServerHello中的server_name扩展和supported_versions扩展。如果一个服务支持TLS 1.3,但协商时却降级到了TLS 1.2,那一定是配置有问题。

好了,到这里,你对照这张图,基本就能把TLS 1.2和1.3的握手差异吃透了。记住,明白了握手,你才具有审计TLS配置的底气。