TLS/SSL协议详解:握手与加密
引言
当你在浏览器地址栏看到那把绿色的小锁,或者网站地址以 https:// 开头时,背后正是 TLS/SSL 协议在默默工作。它保护着你的密码、银行卡信息、聊天记录,让互联网上的数据传输变得安全可靠。
本文将深入剖析 TLS/SSL 协议的完整流程,从握手到加密,从原理到实践,带你理解这个守护互联网安全的基石协议。
一、TLS 与 SSL:一段演进历史
1.1 SSL 时代(1994-1999)
SSL(Secure Sockets Layer)由网景公司(Netscape)开发:
- SSL 1.0:从未公开发布,存在严重安全漏洞
- SSL 2.0(1995):首次发布,但很快被发现存在多个安全问题
- SSL 3.0(1996):重大改进,但仍不够完善
1.2 TLS 时代(1999至今)
TLS(Transport Layer Security)是 SSL 的标准化继任者:
| 版本 | 年份 | 状态 |
|------|------|------|
| TLS 1.0 | 1999 | 已废弃(2021) |
| TLS 1.1 | 2006 | 已废弃(2021) |
| TLS 1.2 | 2008 | 当前主流 |
| TLS 1.3 | 2018 | 推荐使用 |
关键区别:TLS 1.3 大幅简化了握手过程,移除了大量过时和脆弱的算法,将握手时间从 2-RTT 缩短到 1-RTT(甚至 0-RTT)。
二、TLS 握手:建立安全连接的舞蹈
2.1 TLS 1.2 握手流程(完整版)
TLS 握手是一个精心设计的协议交换过程,通常需要 2-RTT(两个往返时间):
客户端 服务器
| |
| -------- ClientHello ----------------> |
| 支持的版本、密码套件、随机数、扩展 |
| |
| <------- ServerHello ------------------ |
| 选择的版本、密码套件、随机数 |
| <------- Certificate ----------------- |
| 服务器证书(含公钥) |
| <------- [ServerKeyExchange] ----------- |
| 密钥交换参数(某些算法需要) |
| <------- ServerHelloDone --------------- |
| |
| -------- ClientKeyExchange -----------> |
| 预主密钥(用服务器公钥加密) |
| -------- [ChangeCipherSpec] -----------> |
| -------- Finished --------------------> |
| 用协商密钥加密的验证消息 |
| |
| <------- [ChangeCipherSpec] ----------- |
| <------- Finished ---------------------- |
| |
| ====== 加密通道建立完成 ====== |
2.2 TLS 1.3 握手优化
TLS 1.3 将握手压缩到 1-RTT:
客户端 服务器
| |
| -------- ClientHello + 密钥共享 ------> |
| 支持的算法、密钥共享、随机数 |
| |
| <------- ServerHello + 密钥共享 + Cert - |
| 选择的算法、完成密钥交换、证书 |
| <------- {Finished} ------------------- |
| 加密的消息验证 |
| |
| -------- {Finished} -----------------> |
| |
| ====== 加密通道建立完成 ====== |
0-RTT 恢复:对于之前连接过的服务器,客户端可以立即发送加密数据,无需握手。
2.3 握手过程中的关键元素
随机数(Random)
客户端和服务器各生成 32 字节的随机数,用于:
- 防止重放攻击
- 确保每次会话密钥唯一
- 增加密钥的熵
密码套件(Cipher Suite)
TLS 1.2 的密码套件格式:TLS密钥交换身份认证加密算法消息认证
示例:TLSECDHERSAWITHAES128GCM_SHA256
| 组件 | 含义 |
|------|------|
| ECDHE | 密钥交换:椭圆曲线 Diffie-Hellman 临时 |
| RSA | 身份认证:RSA 证书 |
| AES128GCM | 对称加密:AES-128 GCM 模式 |
| SHA256 | 消息认证:HMAC-SHA256 |
TLS 1.3 简化为:TLSAES256GCMSHA384(密钥交换和认证已分离)
三、证书与身份验证
3.1 X.509 证书结构
服务器证书包含:
证书
├── 版本号
├── 序列号
├── 签名算法
├── 颁发者(Issuer)
├── 有效期
│ ├── 生效时间
│ └── 过期时间
├── 主体(Subject)
│ └── 通用名称(CN)= 域名
├── 主体公钥信息
│ ├── 算法(RSA/ECDSA)
│ └── 公钥值
├── 扩展
│ ├── 主题备用名称(SAN)← 现代浏览器主要检查此项
│ ├── 密钥用途
│ └── 基本约束
└── 签名
3.2 证书链验证
浏览器验证服务器身份时,会构建证书链:
服务器证书(叶子)
↑ 由中间 CA 签名
中间 CA 证书
↑ 由根 CA 签名
根 CA 证书(内置在操作系统/浏览器中)
验证步骤:
- 检查证书有效期
- 验证域名匹配(CN 或 SAN)
- 验证证书链签名
- 检查证书吊销状态(CRL/OCSP)
- 检查证书透明度(CT Logs)
3.3 证书类型
| 类型 | 验证级别 | 适用场景 |
|------|----------|----------|
| DV(域名验证) | 低 | 个人博客、小型网站 |
| OV(组织验证) | 中 | 企业官网 |
| EV(扩展验证) | 高 | 银行、金融机构 |
四、密钥交换机制
4.1 密钥交换的核心问题
TLS 需要在公开信道上协商出只有双方知道的密钥。主要方法:
4.2 RSA 密钥交换(已废弃)
1. 服务器发送 RSA 公钥(在证书中)
- 客户端生成预主密钥(48字节随机数)
- 客户端用服务器公钥加密预主密钥
- 服务器用私钥解密
致命缺陷:如果服务器私钥泄露,所有历史会话都可被解密(不具备前向保密)。
4.3 Diffie-Hellman 密钥交换
经典 DH
基于离散对数问题:
公开参数:大素数 p,生成元 g客户端 服务器
选择 a,计算 A = g^a mod p
发送 A ---------------> 接收 A
接收 B <--------------- 发送 B = g^b mod p
计算 s = B^a mod p 计算 s = A^b mod p
s = g^(ab) mod p = 共享密钥
ECDHE(椭圆曲线 DH)
使用椭圆曲线密码学,更高效:
曲线:y² = x³ + ax + b (mod p)客户端 服务器
选择私钥 dc,计算公钥 Qc = d_c × G
发送 Qc -------------> 接收 Qc
接收 Qs <------------- 发送 Qs = d_s × G
计算 S = dc × Qs 计算 S = ds × Qc
S = dc × ds × G = 共享点
优势:
- 相同安全强度下,密钥更短(256位 EC ≈ 3072位 RSA)
- 计算速度更快
- 支持前向保密(使用临时密钥)
五、数据加密与完整性保护
5.1 对称加密
握手完成后,使用协商的对称密钥加密应用数据:
| 算法 | 模式 | 特点 |
|------|------|------|
| AES | GCM | 认证加密,硬件加速 |
| AES | CCM | 认证加密,适合受限环境 |
| ChaCha20 | Poly1305 | 流密码,软件实现快 |
5.2 认证加密(AEAD)
现代 TLS 使用 AEAD 模式,同时提供:
- 机密性:加密数据
- 完整性:验证数据未被篡改
- 真实性:验证数据来源
AES-GCM 工作方式:
明文 + 关联数据(AAD)+ 随机数(Nonce)
↓
AES-GCM 加密
↓
密文 + 认证标签(Tag)
5.3 记录协议
TLS 将应用数据分割为记录:
TLS 记录
├── 内容类型(握手/应用数据/告警)
├── 版本号
├── 长度
├── 加密数据
│ ├── 明文片段
│ ├── MAC(消息认证码)
│ └── 填充(块密码需要)
└── 认证标签(AEAD)
六、TLS 安全性分析
6.1 已知攻击与防护
| 攻击 | 目标 | 防护措施 |
|------|------|----------|
| BEAST | CBC 模式漏洞 | 使用 TLS 1.2+,优先 RC4(已废弃) |
| CRIME | 压缩侧信道 | 禁用 TLS 压缩 |
| BREACH | HTTP 压缩 | 禁用 HTTP 压缩或添加随机数据 |
| Heartbleed | OpenSSL 实现漏洞 | 升级 OpenSSL |
| POODLE | SSL 3.0 填充 Oracle | 禁用 SSL 3.0 |
| Logjam | 弱 DH 参数 | 使用 ≥2048 位 DH,禁用导出套件 |
| SWEET32 | 64 位块密码 | 禁用 3DES |
| ROBOT | RSA 填充 Oracle | 禁用 RSA 密钥交换 |
6.2 前向保密(Forward Secrecy)
定义:即使长期私钥泄露,之前的会话也不会被解密。
实现方式:
- 使用 ECDHE 或 DHE 密钥交换
- 每次握手生成临时密钥对
- 握手完成后丢弃临时私钥
6.3 证书固定(HPKP / Expect-CT)
- HPKP:告诉浏览器只接受特定公钥的证书(已废弃,风险太高)
- Expect-CT:要求证书必须被记录到 Certificate Transparency 日志中
七、TLS 1.3 的重大改进
7.1 移除的过时特性
- RSA 密钥交换(不支持前向保密)
- SHA-1、MD5 签名算法
- CBC 模式(BEAST、Lucky13 等攻击)
- 压缩(CRIME、BREACH 攻击)
- 自定义 DHE 组(Logjam 攻击)
7.2 性能提升
| 指标 | TLS 1.2 | TLS 1.3 |
|------|---------|---------|
| 握手 RTT | 2 | 1(0-RTT 恢复) |
| 握手消息数 | 7-9 | 5 |
| 支持的密码套件 | 340+ | 5 |
| 首次连接延迟 | ~2×RTT | ~1×RTT |
7.3 隐私改进
- 加密更多握手消息(除 ClientHello 外)
- 减少可追踪的元数据暴露
- 防止中间人识别客户端/服务器配置
八、实践配置指南
8.1 服务器配置(Nginx 示例)
server { listen 443 ssl http2; server_name example.com;# 证书配置
ssl_certificate /path/to/cert.pem;
sslcertificatekey /path/to/key.pem;# 协议版本(禁用 TLS 1.0/1.1)
ssl_protocols TLSv1.2 TLSv1.3;# 密码套件(优先 AEAD,前向保密)
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;sslpreferserver_ciphers on;
# 会话缓存
sslsessioncache shared:SSL:10m;
sslsessiontimeout 1d;
sslsessiontickets off;# OCSP Stapling
ssl_stapling on;
sslstaplingverify on;
# HSTS(强制 HTTPS)
add_header Strict-Transport-Security "max-age=63072000" always;
}
8.2 安全配置检查清单
- [ ] 禁用 SSL 2.0/3.0 和 TLS 1.0/1.1
- [ ] 仅使用 AEAD 密码套件
- [ ] 启用前向保密(ECDHE/DHE)
- [ ] 使用 ≥2048 位 RSA 或 ≥256 位 EC 证书
- [ ] 启用 HSTS
- [ ] 配置 OCSP Stapling
- [ ] 定期更新证书(有效期 ≤1 年)
- [ ] 监控证书到期时间
8.3 测试工具
# 使用 OpenSSL 测试
openssl sclient -connect example.com:443 -tls13
使用 testssl.sh 全面检测
testssl.sh example.com
使用 SSL Labs 在线检测
https://www.ssllabs.com/ssltest/
九、常见问题解答
Q1:TLS 和 HTTPS 是什么关系?
HTTPS = HTTP + TLS。TLS 是安全传输层协议,HTTPS 是在 TLS 上运行的 HTTP 协议。
Q2:为什么 TLS 1.3 握手更快?
TLS 1.3 将 ServerHello 和密钥交换合并,减少了往返次数。同时移除了不必要的消息类型。
Q3:什么是中间人攻击?TLS 如何防御?
中间人攻击是攻击者伪装成通信双方。TLS 通过:
- 证书验证服务器身份
- 密钥交换确保只有双方知道密钥
- 消息认证码检测数据篡改
Q4:自签名证书安全吗?
自签名证书提供加密,但不提供身份验证。浏览器会显示警告,因为无法验证证书持有者身份。适合内部测试,不适合生产环境。
Q5:TLS 能防止所有攻击吗?
不能。TLS 保护传输安全,但:
- 不保护服务器上的数据
- 不防止应用层漏洞(如 SQL 注入)
- 不防止客户端恶意软件
- 不防止社会工程学攻击
总结
TLS/SSL 协议是现代互联网安全的基石。从 SSL 到 TLS 1.3,协议不断演进,移除脆弱算法,简化握手流程,提升安全性和性能。
核心要点:
- TLS 握手协商加密参数和密钥
- 证书链验证服务器身份
- ECDHE 提供前向保密
- AEAD 同时保护机密性和完整性
- TLS 1.3 更快、更安全、更简单
理解 TLS 不仅是掌握一个协议,更是理解安全通信的基本原理——身份验证、密钥交换、加密传输,这三要素构成了安全通信的完整闭环。
文章编号:NS-CRYPTO-04
系列:网络安全系列 · 密码学篇