TLS 协议基础与演变

3.1 TLS 在安全体系中的定位

TLS 协议到底是什么?说实话,很多工程师学了几年网络,还是把它跟 HTTPS 划等号。其实 TLS 是独立于应用层的安全传输协议。

我个人更愿意把 TLS 理解成一个“安全管道工厂”。它不关心你传的是 HTTP、FTP 还是自定义协议。它只负责两件事:一是证明对方身份,二是加密通信内容。我记得刚开始做 TLS 协议分析时,总觉得它很复杂。后来才发现,核心就这四个服务:机密性、完整性、身份认证、防重放。

安全服务 TLS 实现方式 我踩过的坑
机密性 对称加密(握手阶段协商算法和密钥) 用 AES-GCM 时忘记更新 Nonce,导致加密出错
完整性 MAC(消息认证码)或 AEAD 模式 早期项目用的 CBC + HMAC,容易被 BEAST 攻击
身份认证 数字证书 + 非对称签名 证书链验证不完整,中间人攻击轻松绕过
防重放 序列号 + 随机数(TLS 1.3 用隐式序列号) 国密改造时忘了处理序列号窗口,导致丢包重连频繁

实际上,TLS 并不是加密传输的唯一选择。IPsec 也在网络层做加密,SSH 则在应用层做隧道。但 TLS 在互联网生态中的普及度最高,原因很简单:浏览器支持、标准成熟、适配灵活。

我在项目中遇到过一个取巧的设计——有人把敏感业务直接跑在 TCP 上,前面加一层自定义加密。结果是什么?每次改密算法都要改客户端和服务端两端代码,维护成本翻倍。所以我的建议是:除非你有极致的性能要求,否则别自己造 TLS 轮子。

3.2 TLS 协议框架:两个核心协议

TLS 由两条“轨道”组成,一条跑控制信号,一条跑业务数据。你想想看,这跟操作系统里的内核态和用户态很像。握手协议负责协商密钥和算法,记录协议负责实际加密传输。

3.2.1 握手协议

握手协议是 TLS 最复杂的部分。它要完成:协商版本、交换随机数、验证身份、生成主密钥。TLS 1.2 需要两次往返(2-RTT),TLS 1.3 缩减到一次往返(1-RTT)。嗯,这里要注意,国密套件的握手流程跟国际标准有差异,后面我会专门讲。

我记得第一次调通 TLS 握手时,看到抓包文件里 ClientHello、ServerHello、Certificate、ClientKeyExchange 一整套交互,感觉像是在看一份加密版的“外交协议”。

3.2.2 记录协议

记录协议就简单多了。它把上层数据分成片段,压缩(可选)、加 MAC、加密,然后封装成 TLS 记录发出。收端做逆操作。为什么会设计成两层?说白了是为了复用。握手完成后,业务数据直接走记录协议,不需要再反复协商密钥。

一个小技巧:调试 TLS 问题时,优先看握手阶段的报文。记录协议加密后你看不懂,但握手阶段的 Certificate 和 ServerHello 是明文的(至少部分字段是)。拿 Wireshark 抓包,配合 (pre)-master-secret log 就能解密。

我在项目中遇到过 MTU 分片导致握手失败的问题。TLS 记录最大是 16KB,但底层 TCP 的 MSS 只有 1460 字节左右。如果证书链特别长(比如 4 级 CA),Certificate 消息可能超过 16KB 限制,导致连接断开。解决办法?要么缩短证书链,要么在服务端启用 TLS 分片扩展。

3.3 TLS 版本演进:从 SSL 到 TLS 1.3

很多人分不清 SSL 和 TLS。其实 SSL 是 Netscape 在 90 年代搞的,后来 IETF 接手后改名为 TLS。名字变了,但 DNA 没变。我建议你不要再写“SSL/TLS”这种模糊说法了,2024 年的项目就直接说 TLS。

版本 发布时间 核心变化 我的态度
SSL 2.0 1995 第一个公开版本,安全性极差 别碰
SSL 3.0 1996 引入 HMAC,修复很多漏洞 POODLE 攻击后已废弃
TLS 1.0 1999 RFC 2246,改名为 TLS 可被 BEAST 攻击,建议关闭
TLS 1.1 2006 增加 CBC 防御机制 安全但低效,已过时
TLS 1.2 2008 RFC 5246,支持 GCM/CCM 当前主力,国密首选
TLS 1.3 2018 RFC 8446,1-RTT,移除不安全算法 强烈推荐,但国密支持有限

曾经有一家金融客户找我做安全审计,他们还在用 TLS 1.0。理由是“老系统不敢动”。我当场演示了 BEAST 攻击代码,25 秒内就解出了加密 Cookie。嗯,从那以后他们当天就申请升级了。

TLS 1.3 最大的变化是精简了握手流程,从 2-RTT 降到 1-RTT,并且支持 0-RTT 快速恢复。为什么要砍掉那么多密码套件?你想想看,TLS 1.2 有 37 种密码套件,大部分没人用,还容易留坑。TLS 1.3 只保留 5 种,全是 AEAD 模式,彻底消除了 CBC 模式下的时序攻击隐患。

但 TLS 1.3 也有代价。它对中间件设备(如防火墙、负载均衡)不友好。这些设备需要解密流量做安全检测,TLS 1.3 的加密握手让它们无法轻易拆包。另外,国密算法在 TLS 1.3 中的标准化工作还没完全结束,所以当前国密项目的主流选择还是 TLS 1.2。

3.4 DTLS:当 TLS 遇上 UDP

有些场景不能用 TCP,比如视频通话、物联网传感器上报。TLS 依赖 TCP 的可靠传输和有序性,不能直接用。DTLS(Datagram TLS)就是为解决这个问题诞生的。它在 TLS 基础上增加了序列号、重传机制、分片重组等逻辑,但保持了跟 TLS 相近的安全强度。

我在做视频会议平台的国密改造时,就遇到了 DTLS 的问题。标准 DTLS 支持的是国际算法,国密 DTLS 的实现还不太成熟。我们当时选了折中方案:信令走 TLS 加密,媒体流走 SRTP(使用国密 SM4 加密)。

这里有个容易犯的错:DTLS 的握手超时跟 TCP 完全不同。TCP 有内核帮我们做重传,DTLS 要应用层自己管理超时和重传。有过一个工程师把 DTLS 超时设为 10 秒,丢一个握手包要等 10 秒才重试,用户体验极差。我建议 DTLS 的初始超时设在 100ms 左右,按指数退避增长,最大不超过 1 秒。

3.5 本章知识体系:一张图看懂

下面我用一张 SVG 图把 TLS 协议体系串起来。这张图是我做培训时最常用的,学员反馈说“比看 RFC 三小时都管用”。放心,它不复杂,就是四个层次从下往上递进。

TLS 协议体系总览 TLS 协议体系总览(核心知识图谱) 应用层协议 HTTP/2 · HTTP/1.1 · WebSocket · gRPC · 自定义协议 TLS 握手协议(控制面) 版本协商 ClientHello / ServerHello 身份认证 证书 · 签名验证 密钥交换 ECDHE 或 SM2 密钥协商 主密钥生成 PRF 派生 TLS 记录协议(数据面) 分片 + 压缩(可选) 加密(AEAD / CBC) MAC 完整性校验 封装 TLS 记录 底层传输协议 TCP(TLS) · UDP(DTLS)

从这个图你能看到,TLS 协议体系是层层递进的。应用层数据先被握手协议处理(协商参数、验证身份),然后交给记录协议加密打包,最后通过 TCP 或 UDP 发出去。国密改造要动的主要是握手协议中的密码套件和证书格式,记录协议的加密算法换一下就行,整体框架不动。