第1章 TLS协议概述与握手流程简介

我调过至少上百个TLS握手包。大家常问的一个问题是——TLS到底是什么?说白了,它就是一套加密握手流程,保证你上网时数据不会被别人偷看或篡改。

你想想看,没有TLS,你在网上提交的密码、信用卡号,全是明文传输。用Wireshark随便一抓就是一条裸数据。后来大家觉得不行,才有了SSL/TLS这套协议。

1.1 TLS协议在OSI模型中的位置

TLS位于传输层(TCP)和应用层(HTTP、FTP等)之间。它不是改造传输层,也不是改造应用层,而是在中间插了一层加密。

OSI层级 典型协议 TLS相关
应用层 HTTP、SMTP HTTPS(HTTP over TLS)
表示层 (无) TLS握手协议、记录协议
传输层 TCP、UDP TLS承载在TCP之上

我在项目中遇到过有人把TLS跟TCP搞混。其实很简单:TCP只管丢包重传、流量控制,不关心数据内容。TLS才负责加密、身份验证。两者一配合,业务数据才能安全到达。

1.2 TLS的两个核心子协议

刚学TLS时,我被各种子协议绕得头晕。后来我自己捋了一下,核心就两个:

  • TLS记录协议(Record Protocol):负责将上层数据分片、压缩(可选)、加密、添加MAC。说白了,就是打包加密数据的搬运工。
  • TLS握手协议(Handshake Protocol):负责双方交换参数、验证身份、生成密钥。握手结束之前,所有数据都是明文或只有部分保护。

嗯,这里要注意:Wireshark里看到的“Client Hello”、“Server Hello”、“Certificate”都属于握手协议。你抓包排错,90%的时间都在看这些握手消息。

1.3 握手流程核心步骤(1.2版本)

我个人习惯把TLS 1.2握手分成四个阶段:

  1. 阶段一:Hello交换——客户端发Client Hello(支持的密码套件、TLS版本、随机数),服务端回复Server Hello(选定的密码套件、版本、随机数)。
  2. 阶段二:证书交换——服务端发Certificate(公钥证书),可选发Server Key Exchange(如DH参数),最后发Server Hello Done。
  3. 阶段三:客户端密钥交换——客户端发Certificate(如果有客户端证书),发Client Key Exchange(用服务端公钥加密的预主密钥),发Certificate Verify(如果客户端证书认证)。
  4. 阶段四:握手完成——双方发Change Cipher Spec(通知对方后续加密),发Finished(验证握手完整性)。

避坑指南:我曾经见过一个线上故障,客户端发完Client Hello后服务端一直没回包。查了半天,发现是客户端支持的密码套件列表太老,服务端一个都不认。Wireshark里看就是单向流量,服务端直接丢掉了连接。

1.4 核心概念:密码套件(Cipher Suite)

密码套件决定了用什么算法来做密钥交换、身份验证、对称加密和MAC。Wireshark里一眼就能看到,比如 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256。

我建议初学者先把套件拆开看:

字段 示例 说明
密钥交换 ECDHE 基于椭圆曲线的临时DH,支持前向安全
身份验证 RSA 用RSA签名验证证书
对称加密 AES_128_GCM 128位AES,GCM模式(同时提供加密和完整性校验)
MAC/PRF SHA256 伪随机函数和消息认证码使用SHA-256

你抓包时,如果看到套件里带“RC4”或“CBC”,要留个心眼——这些算法存在已知漏洞。我见过不少老旧系统还在用RC4,换来的是被破解的风险。

1.5 TLS版本演化概览

从SSL 2.0到TLS 1.3,版本迭代主要围绕安全性和握手延迟。我个人认为,了解历史版本能帮你快速定位兼容性问题。

版本 发布年份 核心变化 现状
SSL 2.0 1995 最先商用,但漏洞极多 已废弃,抓到就算异常
SSL 3.0 1996 引入MAC、改进握手 已废弃(POODLE攻击后)
TLS 1.0 1999 基于SSL 3.0,改命名 逐渐淘汰
TLS 1.1 2006 防御CBC攻击 不再推荐
TLS 1.2 2008 支持AES-GCM、SHA256,移除IDEA/DES 广泛使用
TLS 1.3 2018 精简握手、移除不安全算法、0-RTT 推荐使用

我个人的经验:在Wireshark里看TLS版本号字段,注意有些客户端/服务端会协商到较低版本。我记得有一次,服务端明明配了TLS 1.2,但客户端只发了SSL 3.0的Client Hello,最终连接失败。这种兼容性问题,抓包一看就知道。

1.6 握手流程核心流程图

TLS 1.2 完整握手过程 客户端(Client) 服务端(Server) 发送ClientHello 客户端发起连接 回复ServerHello 协商版本/套件/随机数 发送Certificate 服务端公钥证书 Server Key Exchange DH参数等密钥交换数据 Server Hello Done Client Key Exchange 预主密钥加密传输 Change Cipher Spec Finished 握手验证通过 Finished ① Hello交换阶段 ② 证书与密钥交换参数 ③ 客户端密钥交换与CCS ④ 握手完成与验证

这张图是我梳理TLS 1.2握手时最常用的参考。你注意看,服务端在第二阶段会连续发多条消息(Certificate、Server Key Exchange、Server Hello Done),而客户端在第三阶段也是连续发(Client Key Exchange、CCS、Finished)。用Wireshark抓包时,能看到这些消息的顺序和内容。我建议你用这张图对照实际抓包,一眼就能看出哪一步卡住了。

1.7 Wireshark抓包前的准备

正式开始抓包前,有几个小习惯我建议你养成:

  • 使用显示过滤器:直接输入 tls 或 ssl,只显示TLS流量,别被其他包干扰。
  • 关注TCP握手:TLS握手必须在TCP三次握手完成后才开始。如果TCP都没建立,TLS包根本不会出现。我见过有人死盯TLS包,结果问题是TCP SYN被防火墙丢了。
  • 启用TLS解密:如果你有服务器私钥或预主密钥日志,可以在Wireshark里配置解密,看到加密后的HTTP请求内容。这个后面章节会详细讲。
  • 抓全所有包:用 -w 参数把完整报文存下来,别只抓一部分。因为很多握手故障需要看前几个包才能定位。

我自己的习惯是把抓包文件命名成 故障现象_时间.pcapng,比如 握手超时_20250331.pcapng。这样回头翻看时,不用回忆“这个包是哪个故障”。

1.8 本章小结

TLS本质上是一套加密握手协议。理解握手流程,你就能用Wireshark判断问题出在哪个阶段。版本变迁、密码套件选择、证书传递,这些都是抓包排错的基础。后面的章节,我会带你一条一条包地过,拆解真实的握手故障场景。