一、TLS协议基础回顾:标准握手流程

说到TLS握手,我得先坦白一件事。早些年我刚接触密码学的时候,总觉得握手就是“你好 - 你好 - 加密 - 结束”,感觉没啥技术含量。后来被生产环境的一个超时故障折腾了三天,才发现握手里的门道远比我想象的多。

今天,咱们就好好聊聊标准TLS握手。说白了,这是所有加密通信的基石。你后面要理解国密TLS,这套标准流程必须得吃透。

1.1 为什么需要握手?

你想想看,如果两个人要在不安全的网络上聊悄悄话,第一步该干啥?

肯定得先确认对方身份,再商量一个只有你俩知道的密钥。对吧?TLS握手做的就是这件事。它解决三个核心问题:

  • 身份验证:确保你连的是真服务器,不是钓鱼的
  • 密钥协商:安全地确定一个用于加密数据的对称密钥
  • 参数协商:选择双方都支持的协议版本、加密套件等

我当年在做一个金融项目时,就因为握手阶段的证书验证没做好,导致中间人攻击风险。那之后,我对握手流程的每个细节都不敢马虎。

核心原则:TLS握手的设计目标,是在不可信的信道上建立一个可信的安全通道。所有握手消息都必须是防篡改的。

1.2 标准TLS 1.2 完整握手流程

TLS 1.2是目前最广泛使用的版本。咱们画一个流程图看看,这样更直观:

TLS 1.2 完整握手流程图 客户端 (Client) 服务端 (Server) ① ClientHello 版本 / 随机数 / 加密套件 ② ServerHello 选择套件 / 随机数 ③ Certificate 服务端证书 / 公钥 ④ ServerHelloDone 消息结束标志 ⑤ 验证证书 生成预主密钥 ⑥ ClientKeyExchange 用服务端公钥加密预主密钥 ⑦ 私钥解密 得到预主密钥 ⑧ 派生主密钥 ⑧ 派生主密钥 ⑨ Finished 加密握手消息验证 ⑩ Finished 加密握手消息验证 双向身份验证仅在双向认证场景

你看这个图,很清晰是吧?客户端先发个"招呼"——ClientHello。里面带着自己支持的版本号、一个随机数,还有一长串加密套件列表。

服务端收到后,从列表里挑一个自己也能支持的,然后回复ServerHello。同时把自己的证书也发过去。这里我见过不少坑——证书链不完整、证书过期、域名不匹配,但凡有一个出问题,握手就会失败。

常见陷阱:我曾经遇到过生产环境的TLS握手间歇性失败。排查了两天才发现,是中间防火墙把超过一定大小的证书链给截断了。小证书没事,大证书就断。所以证书链的大小也得留意。

1.3 密钥派生过程

嗯,这里要重点说一下密钥怎么来的。很多初学者觉得握手完成直接就能加密了,其实中间还有一套精密的密钥派生流程。

标准流程里,密钥派生分为三步:

  1. 预主密钥 (Pre-Master Secret):客户端生成一个随机值,用服务端公钥加密后传过去
  2. 主密钥 (Master Secret):双方各自用预主密钥 + 两个随机数,通过PRF(伪随机函数)计算得到
  3. 会话密钥 (Session Keys):从主密钥继续派生,生成用于对称加密的密钥、初始化向量、HMAC密钥等

一个小技巧:我个人习惯在调试时把握手的随机数和预主密钥都记录下来。虽然生产环境不能这么搞,但开发阶段这样做,对理解密钥派生过程特别有帮助。

1.4 握手中的关键数据结构

咱们来看看握手里实际传的是什么。我把几个核心消息的数据结构整理成一个表,方便你对照:

消息类型 主要字段 作用
ClientHello 版本号、随机数(32字节)、加密套件列表、压缩算法列表 发起连接,告知自身能力
ServerHello 版本号、随机数、选定的加密套件、会话ID 响应连接,确定加密参数
Certificate X.509证书链(一个或多个证书) 提供服务端身份凭证
ClientKeyExchange 加密后的预主密钥(RSA场景)或DH公钥 传递密钥协商材料
Finished 基于所有握手消息的MAC值 验证握手完整性,防止篡改

1.5 TLS 1.3 的变化

说到最新版本,TLS 1.3 其实做了挺大的简化。我记得第一次看1.3规范的时候,心想“这也差太多了吧”。

核心变化有两点:

  • 握手压缩为1-RTT:在以往需要2次往返才能完成的事,现在1次就够了
  • 移除不安全的算法:RSA密钥交换被砍了,强制使用DH类算法,实现前向安全性

不过在实际项目里,我建议你优先支持1.2。因为1.3虽然更快,但有些旧系统还在用1.2,兼容性上1.2更稳妥。后面讲国密TLS的时候,咱们会看到国密也主要基于1.2进行改造。

为什么说前向安全性重要?——如果握手时用的是RSA加密预主密钥,服务端的私钥一旦泄露,之前记录的所有流量都能被解密。而DH类算法每次会话使用临时密钥,私钥泄露不影响过去的会话。我在安全审计中至少见过三个项目在这上面踩过坑。

1.6 总结:标准TLS握手到底做了什么?

好了,咱们把标准TLS握手捋一遍。其实核心就这几件事:

  1. 能力协商:双方确认用什么版本、什么算法
  2. 身份验证:通过数字证书确认服务端身份(有时也验证客户端)
  3. 密钥协商:安全地生成一个只有双方知道的对称密钥
  4. 完整性验证:确认握手过程没被篡改

这套流程看起来很完善,对吧?但为什么我们还需要国密TLS呢?原因很简单:标准TLS用的加密算法,比如RSA、AES、SHA-256,都是国际算法。在某些行业(比如金融、政务),政策要求必须使用国家密码管理局批准的算法。这就是我们后面要深入探讨的内容。

下个章节我们会看标准TLS和国密TLS在握手上的具体差异,以及如何把国密算法套件“塞”进TLS框架里。别走开。你先把这个标准流程吃透,后面学国密会轻松很多。