4. TLS 协议基础:握手协议、记录协议、密码套件与 TLS 1.2/1.3 对比

各位同学,欢迎来到第四讲。今天我们要啃一块硬骨头——TLS 协议本身。说实话,很多搞了几年安全的工程师,对 TLS 的理解也停留在“哦,就是那个 HTTPS 用的加密协议”。但咱们做硬件密钥和双向认证,必须把它的骨架摸清楚。

我当年第一次调试硬件密钥与服务器的双向认证时,抓包看到一堆 Client Hello、Server Hello、Certificate Verify,完全懵了。后来花了整整一周,把 RFC 5246 和 RFC 8446 翻了个底朝天,才算真正搞明白。今天我把这些经验浓缩一下,带你快速掌握 TLS 的核心。

4.1 TLS 协议栈:两层结构

TLS 协议其实分两层:底层是记录协议,上层是握手协议(以及告警协议、Change Cipher Spec 协议等)。你可以把记录协议想象成“运输卡车”,握手协议就是“车上装的货物”。

核心理解:记录协议负责数据的分片、压缩、加密、完整性校验;握手协议负责身份认证和密钥协商。两者配合,才能完成一次安全的 TLS 连接。

先看记录协议。它做的事情很简单:把上层数据切成不超过 2^14 字节的片段,然后选择是否压缩(现在基本不压缩了),再用当前会话的密钥加密,最后加上 MAC 标签。每个记录都有一个 5 字节的头部,包含内容类型、版本号和长度。

// TLS 记录协议头部结构(5 字节)
struct {
    ContentType type;       // 1 字节:20=ChangeCipherSpec, 21=Alert, 22=Handshake, 23=Application
    ProtocolVersion version; // 2 字节:如 0x0303 表示 TLS 1.2
    uint16 length;          // 2 字节:负载长度
} RecordHeader;

我个人习惯在抓包时先看记录层头部。如果看到 type=22,说明这是握手消息;type=23 就是应用数据。这个区分在调试双向认证时特别有用——你能一眼看出握手卡在哪一步。

4.2 握手协议:TLS 1.2 的完整流程

握手协议才是重头戏。咱们先看 TLS 1.2 的完整握手流程,因为硬件密钥和双向认证主要基于这个版本。

提示:下面的流程图展示了 TLS 1.2 完整握手(含双向认证)的 10 个核心步骤。建议你对照着看后面的文字说明。

TLS 1.2 完整握手流程图(含双向认证) 客户端 服务端 ① ClientHello ② ServerHello ③ 服务端证书 ④ CertificateRequest ⑤ ServerHelloDone ⑥ 客户端证书 ⑦ ClientKeyExchange ⑧ CertificateVerify ⑨ Finished 橙色节点表示双向认证特有的步骤

咱们一步步拆解这个流程。我当年第一次看这个图,觉得好复杂,但后来发现其实就三个大阶段:

  1. Hello 阶段(步骤 1-5):双方打招呼,交换能力(密码套件、随机数、扩展),服务端发送证书并可选地请求客户端证书。
  2. 密钥交换阶段(步骤 6-8):客户端发送证书(如果被请求)、交换预主密钥、用私钥签名证明身份。
  3. 完成阶段(步骤 9):双方切换加密套件,发送 Finished 消息验证握手完整性。

注意:在双向认证中,步骤 ④ 和 ⑥ 是必须的。我曾经遇到一个项目,服务端发了 CertificateRequest,但客户端证书里没有包含数字签名密钥用法(Key Usage),结果握手一直失败。抓包看了半天才发现是证书扩展字段的问题。

4.3 密码套件:TLS 的“加密配方”

密码套件(Cipher Suite)是 TLS 握手中协商的核心内容。它定义了四个关键算法:密钥交换算法、认证算法、对称加密算法、消息认证码算法。

举个例子,TLS 1.2 中常见的密码套件:

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
│      │     │         │         │
│      │     │         │         └── 伪随机函数 (PRF) 和 MAC 算法
│      │     │         └──────────── 对称加密算法 (AES-128-GCM)
│      │     └────────────────────── 认证算法 (RSA 签名)
│      └──────────────────────────── 密钥交换算法 (ECDHE)
└─────────────────────────────────── TLS 协议版本

我个人建议,在硬件密钥场景中优先选择 ECDHE 作为密钥交换算法。为什么?因为 ECDHE 支持前向安全性(PFS),即使服务器私钥泄露,之前的会话也无法被解密。RSA 密钥交换就不行。

组件 常见选项 硬件密钥适配建议
密钥交换 ECDHE, DHE, RSA 优先 ECDHE(P-256 或 X25519)
认证 RSA, ECDSA, EdDSA 硬件密钥通常支持 RSA 2048/4096 和 ECDSA P-256
对称加密 AES-GCM, ChaCha20-Poly1305 AES-GCM 硬件加速常见,ChaCha20 适合无 AES 加速的 IoT 设备
MAC/PRF SHA256, SHA384 SHA256 足够,SHA384 用于更高安全等级

避坑指南:我曾经在调试一款国产硬件密钥时,发现它只支持 RSA 密钥交换,不支持 ECDHE。结果和现代服务器(只开 ECDHE 套件)握手失败。解决方案是让服务器降级支持 RSA 套件,或者换硬件。所以采购硬件密钥时,一定要确认它支持的密码套件列表。

4.4 TLS 1.3:握手协议的革命

TLS 1.3(RFC 8446)是 TLS 协议的一次重大升级。它把握手从 2-RTT 降到了 1-RTT(甚至 0-RTT),同时砍掉了一堆不安全的算法。

咱们直接对比一下 TLS 1.2 和 1.3 的核心差异:

对比维度 TLS 1.2 TLS 1.3
握手延迟 2-RTT(完整握手) 1-RTT(完整握手),0-RTT(会话恢复)
支持的密码套件 37+ 种(含大量不安全套件) 5 种(仅 AEAD 套件)
密钥交换 支持 RSA、DH、ECDH 等多种 仅支持 (EC)DHE,强制前向安全
握手消息加密 Finished 消息后才加密 ServerHello 之后即加密
会话恢复 Session ID / Session Ticket PSK + (EC)DHE 或 PSK-only
证书认证 支持双向认证 支持双向认证(但实现更复杂)

你可能会问:TLS 1.3 这么好,为什么硬件密钥场景还在大量用 TLS 1.2?

原因有三:

  • 兼容性:很多硬件密钥的固件比较老,只实现了 TLS 1.2 协议栈。升级固件成本高、风险大。
  • 双向认证复杂度:TLS 1.3 的 CertificateVerify 消息计算方式变了,而且握手消息加密后,调试难度大增。我见过好几个团队在 TLS 1.3 双向认证上踩坑。
  • 0-RTT 的安全风险:0-RTT 存在重放攻击问题,不适合金融级双向认证场景。

我的建议:如果项目从零开始,且硬件支持 TLS 1.3,优先用 1.3。但如果要兼容现有硬件密钥生态,TLS 1.2 仍然是稳妥选择。咱们这门课会同时覆盖两个版本,但重点放在 TLS 1.2 上,因为硬件密钥双向认证的实战场景中,TLS 1.2 占了 80% 以上。

4.5 记录协议:数据加密与完整性保护

握手完成后,应用数据就通过记录协议传输了。TLS 1.2 的记录协议使用MAC-then-Encrypt(先计算 MAC,再加密),而 TLS 1.3 强制使用AEAD(认证加密,如 AES-GCM)。

这里有个历史教训。TLS 1.2 的 MAC-then-Encrypt 方案存在填充预言攻击(Padding Oracle Attack),比如著名的 POODLE 攻击。所以后来大家都转向 AEAD 了。

// TLS 1.2 记录协议加密流程(以 AES-CBC + HMAC-SHA1 为例)
原始数据: [应用数据]
步骤 1: 计算 MAC → [应用数据 | MAC]
步骤 2: 填充 → [应用数据 | MAC | 填充]
步骤 3: 加密 → [IV | 密文]

// TLS 1.3 记录协议加密流程(以 AES-128-GCM 为例)
原始数据: [应用数据]
步骤 1: 直接 AEAD 加密 → [Nonce | 密文 | 认证标签]

在硬件密钥场景中,记录协议有一个关键点:序列号。每个记录都有一个 64 位的序列号,用于防止重放攻击。硬件密钥内部需要维护这个序列号状态,掉电后要能恢复。我见过一个产品,掉电后序列号重置为 0,结果被攻击者重放旧记录,导致业务异常。

注意:如果你在硬件密钥中实现 TLS 协议栈,务必把序列号存储在非易失性存储器中,并且每次写入前做磨损均衡。否则频繁写入会烧坏 Flash。

4.6 小结:TLS 协议的核心要点

好了,这一章的内容不少。咱们回顾一下核心要点:

  • TLS 协议分两层:记录协议(加密传输)和握手协议(认证和密钥协商)。
  • TLS 1.2 完整握手需要 2-RTT,双向认证增加 CertificateRequest 和 CertificateVerify 两个步骤。
  • 密码套件由四个算法组成,硬件密钥场景优先选择 ECDHE + ECDSA + AES-GCM + SHA256。
  • TLS 1.3 更快、更安全,但硬件兼容性和双向认证实现复杂度是主要挑战。
  • 记录协议的序列号管理在硬件实现中是个容易忽略的坑。