第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握手分成四个阶段:
- 阶段一:Hello交换——客户端发Client Hello(支持的密码套件、TLS版本、随机数),服务端回复Server Hello(选定的密码套件、版本、随机数)。
- 阶段二:证书交换——服务端发Certificate(公钥证书),可选发Server Key Exchange(如DH参数),最后发Server Hello Done。
- 阶段三:客户端密钥交换——客户端发Certificate(如果有客户端证书),发Client Key Exchange(用服务端公钥加密的预主密钥),发Certificate Verify(如果客户端证书认证)。
- 阶段四:握手完成——双方发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握手时最常用的参考。你注意看,服务端在第二阶段会连续发多条消息(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判断问题出在哪个阶段。版本变迁、密码套件选择、证书传递,这些都是抓包排错的基础。后面的章节,我会带你一条一条包地过,拆解真实的握手故障场景。