TLS协议基础:从历史到核心机制

说到传输层加密,TLS 是绕不开的基石。

我记得刚入行那会儿,还在用 SSL 3.0。后来 POODLE 漏洞一出,全线升级 TLS 1.2,那阵子真是加班加到手软。嗯,这段历史咱们得聊清楚。

TLS/SSL 的历史:一条补丁之路

SSL(Secure Sockets Layer)是网景公司 90 年代搞出来的。一开始是 SSL 2.0(1995),但漏洞太多。紧接着 SSL 3.0(1996)算是真正能用的版本。

后来 IETF 接手,改名叫 TLS(Transport Layer Security)。TLS 1.0 基本就是 SSL 3.0 的微调。然后有了 1.1(2006)、1.2(2008)、1.3(2018)。

说白了,每个版本都是在给前一个版本“擦屁股”。

版本 发布年份 状态 我的看法
SSL 2.0 1995 已弃用 别碰,漏洞多到数不清
SSL 3.0 1996 已弃用 POODLE 漏洞后没人敢用
TLS 1.0 1999 已弃用 BEAST 攻击年代的噩梦
TLS 1.1 2006 已弃用 过渡产品,不推荐
TLS 1.2 2008 广泛使用 目前最稳妥的选择
TLS 1.3 2018 推荐 更快、更安全、更简洁
避坑指南: 我曾经接手过一个老项目,TLS 1.0 还在线上跑。一查日志,大量 BEAST 攻击尝试。立刻禁掉 1.0/1.1,只留 1.2。你想想看,有些坑不踩不知道疼。

握手协议:双方如何建立信任

TLS 握手是客户端和服务器之间的“相亲”过程。互相验证身份,协商加密参数。

我拆解一下 TLS 1.2 的完整握手流程(TLS 1.3 简化了很多,但理解 1.2 很重要):

  1. ClientHello:客户端发支持的最高版本、密码套件列表、随机数。
  2. ServerHello:服务器选好版本、密码套件、发自己的随机数。
  3. Certificate:服务器发数字证书(含公钥)。
  4. ServerHelloDone:服务器说“我的信息发完了”。
  5. ClientKeyExchange:客户端用服务器公钥加密一个 Pre-Master Secret,发过去。
  6. ChangeCipherSpec:双方切换加密模式。
  7. Finished:握手完成,开始加密通信。

你看,这中间有两个随机数和一个预主密钥。三者一起算出主密钥(Master Secret),后续的会话密钥全靠它派生。

经验之谈: 我做过一个压测案例——每次握手都涉及非对称解密,服务器 CPU 直接飙到 100%。那时候才意识到,会话复用(Session Resumption)有多重要。握手越少,性能越好。

对了,TLS 1.3 把握手从 2-RTT 降到了 1-RTT(甚至 0-RTT),砍掉了不少冗余步骤。具体来说,它把密钥交换和证书验证合并了。

TLS 1.2 握手流程 TLS 1.2 握手流程(简化) 客户端 服务器 ① ClientHello(版本、套件、随机数) ② ServerHello(选定套件、随机数) ③ 服务器证书(含公钥) ④ ServerHelloDone ⑤ ClientKeyExchange(加密后的 Pre-Master) 计算主密钥 计算主密钥 ⑥ ChangeCipherSpec (双方通知切换加密) ⑦ Finished

记录协议:加密数据怎么打包

握手完成之后,真正的数据传输就交给记录协议(Record Protocol)了。

它的活儿很简单:把上层的数据分片、压缩(可选)、加密、加上消息认证码(MAC),然后丢给 TCP 去发送。

记录协议的每个包有个固定头部:内容类型、版本号、长度。类型有 20(ChangeCipherSpec)、21(Alert)、22(Handshake)、23(Application Data)。

小细节: 我之前调一个 HTTPS 代理程序,抓包发现有些 SSL 记录的长度字段竟然是 0。查了 RFC 才知道,那是 TLS 空记录,用于保活或避免流量分析。嗯,协议里坑挺多。

记录协议能保证:

  • 机密性:数据加密,用对称密钥
  • 完整性:MAC 校验,防止篡改
  • 防重放:序列号机制

密码套件:加密算法的“套餐”

密码套件(Cipher Suite)就是一组算法的组合。比如常见的 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256。

拆开来看:

部分 含义 例子
密钥交换 如何安全地协商对称密钥 ECDHE(椭圆曲线 Diffie-Hellman 临时密钥)
身份验证 用证书验证对方身份 RSA、ECDSA
对称加密 加密实际数据 AES_128_GCM、ChaCha20
消息认证 完整性校验 SHA256(与 GCM 配合时隐式提供)

我个人强烈建议:优先使用 AEAD 加密算法(如 GCM 或 ChaCha20-Poly1305)。它们把加密和认证合二为一,既安全又高效。TLS 1.3 干脆强制所有套件必须用 AEAD。

避坑指南: 我曾经碰到过一个客户,他们还在用 CBC 模式的套件(比如 AES_128_CBC_SHA)。BEAST 和 Lucky13 攻击专打这种模式。当时我直接给他们的 NGINX 配了张白名单:只允许 ECDHE + GCM 的套件。记住,现代服务禁用 CBC 和 RC4,坚决移除。

好了,TLS 协议基础就聊到这儿。下次咱们讲如何把 Tokenization 和 TLS 结合起来,做落地实战。