TLS 握手与加密通信
为什么需要 TLS
HTTP 协议最初设计为明文传输协议,所有通信内容都以纯文本形式在网络中传输。这种设计在互联网早期是合理的,但随着网络应用的普及和敏感数据的增多,明文传输带来了严重的安全风险。
窃听风险
在明文传输模式下,任何能够访问网络链路的攻击者都可以轻易读取通信内容。这包括:
- 同一局域网内的其他用户
- 网络服务提供商(ISP)
- 恶意的路由器或交换机
- 公共 Wi-Fi 网络的运营者
攻击者可以使用诸如 Wireshark、tcpdump 等网络抓包工具捕获数据包,直接查看其中的内容。这意味着用户名、密码、信用卡号、私密消息等敏感信息都会暴露在攻击者面前。
篡改风险
明文传输不仅允许攻击者读取内容,还允许他们修改传输的数据。攻击者可以在数据包经过的任何位置插入、删除或修改内容,而接收方难以察觉。例如:
- 将银行转账金额从 100 元改为 10000 元
- 修改电子邮件的内容
- 在网页中插入恶意脚本
- 替换下载的软件包
冒充风险
由于缺乏身份验证机制,攻击者可以冒充合法的服务器与客户端通信。客户端无法确认与之通信的服务器是否真实可信。这使得钓鱼攻击成为可能:攻击者搭建一个与真实银行网站外观相似的假冒网站,诱骗用户输入敏感信息。
TLS(Transport Layer Security,传输层安全协议)正是为了解决这些问题而设计的。它通过加密通信内容防止窃听,通过消息认证码(MAC)防止篡改,通过数字证书验证服务器身份防止冒充。
密码学基础
理解 TLS 需要掌握一些基础的密码学概念。TLS 综合运用了多种密码学技术来实现安全通信。
对称加密
对称加密使用相同的密钥进行加密和解密。常见的对称加密算法包括 AES(Advanced Encryption Standard)、DES、3DES 等。
AES 是目前最广泛使用的对称加密算法,支持 128 位、192 位和 256 位密钥长度。AES 的优点是加密速度快,适合加密大量数据。但对称加密面临密钥分发问题:通信双方必须事先共享密钥,而如何在公开的网络环境中安全地共享密钥是一个挑战。
非对称加密
非对称加密使用一对密钥:公钥和私钥。公钥可以公开分发,私钥必须保密。用公钥加密的数据只能用私钥解密,用私钥签名的数据可以用公钥验证。
常见的非对称加密算法包括 RSA 和 ECC(Elliptic Curve Cryptography)。RSA 基于大整数分解的数学难题,ECC 基于椭圆曲线离散对数问题。相比 RSA,ECC 可以用更短的密钥实现同等的安全性,计算效率更高。
非对称加密解决了密钥分发问题,但计算成本远高于对称加密,不适合加密大量数据。因此 TLS 使用非对称加密来协商对称密钥,然后使用对称密钥加密实际通信数据。
哈希函数
哈希函数将任意长度的输入数据映射为固定长度的输出值(哈希值或摘要)。常见的哈希算法包括 SHA-256、SHA-1、MD5 等。SHA-256 生成 256 位的哈希值,是当前推荐的哈希算法。
哈希函数具有以下特性:
- 单向性:从哈希值无法推导出原始数据
- 抗碰撞性:很难找到两个不同的输入产生相同的哈希值
- 雪崩效应:输入的微小变化会导致哈希值的巨大变化
哈希函数用于验证数据完整性,确保数据在传输过程中未被篡改。
数字签名
数字签名结合了非对称加密和哈希函数,用于验证消息的真实性和完整性。签名过程如下:
- 发送方对消息计算哈希值
- 用私钥对哈希值加密,生成数字签名
- 将消息和数字签名一起发送
验证过程如下:
- 接收方用发送方的公钥解密数字签名,得到哈希值
- 接收方对接收到的消息重新计算哈希值
- 比较两个哈希值,如果相同则验证通过
数字签名确保消息确实来自声称的发送方(因为只有发送方持有私钥),并且内容未被篡改(因为任何修改都会导致哈希值不匹配)。
数字证书
数字证书(X.509 证书)是用于验证公钥所有权的数字文档。证书由受信任的第三方机构——证书颁发机构(Certificate Authority,CA)签发。
证书包含以下主要信息:
- 证书持有者的名称和公钥
- 证书颁发机构(CA)的名称
- 证书有效期
- 证书序列号
- CA 对证书的数字签名
证书的目的是将公钥与实体身份绑定起来,确保你使用的公钥确实属于声称的实体,而非攻击者。
证书链
在实际应用中,CA 通常采用层次结构。根 CA 签发中间 CA 的证书,中间 CA 再签发终端实体(如网站服务器)的证书。这就形成了证书链。
验证证书时,需要逐级验证证书链:
- 验证服务器证书是否由中间 CA 签发
- 验证中间 CA 证书是否由根 CA 签发
- 验证根 CA 证书是否受信任(通常预置在操作系统或浏览器中)
如果证书链中的任何一环验证失败,则整个证书链无效。
证书颁发机构(CA)
CA 是受信任的第三方机构,负责签发和管理数字证书。CA 的核心职责包括:
- 验证证书申请者的身份
- 签发数字证书
- 维护证书吊销列表(CRL)
- 提供在线证书状态协议(OCSP)服务
常见的商业 CA 包括 DigiCert、Sectigo、GlobalSign 等。此外,Let’s Encrypt 提供免费的自动化证书服务。
TLS 1.2 握手过程
TLS 握手是客户端和服务器建立安全通信通道的过程。TLS 1.2 的完整握手过程通常需要 2-RTT(往返时间)。以下是详细的握手步骤:
1. ClientHello
客户端发起握手,发送 ClientHello 消息,包含以下内容:
- 支持的 TLS 版本(如 TLS 1.2)
- 支持的密码套件列表(如 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
- 支持的压缩方法
- 随机数(Client Random,32 字节)
- 扩展字段(如 Server Name Indication、支持的椭圆曲线等)
密码套件指定了密钥交换算法、认证算法、对称加密算法和 MAC 算法的组合。
2. ServerHello
服务器响应 ServerHello 消息,包含以下内容:
- 选定的 TLS 版本
- 选定的密码套件
- 选定的压缩方法
- 随机数(Server Random,32 字节)
- 会话 ID(可选,用于会话恢复)
服务器从客户端提供的选项中选择双方都支持的最优配置。
3. Certificate
服务器发送数字证书链。证书链从服务器证书开始,依次向上直到根证书。客户端使用这些证书验证服务器的身份。
如果使用匿名密钥交换(不推荐),则不发送此消息。
4. ServerKeyExchange
如果选定的密码套件需要(如使用 DHE 或 ECDHE 密钥交换),服务器发送此消息,包含:
- 密钥交换参数(如椭圆曲线参数、临时公钥)
- 对这些参数的签名
签名使用服务器的私钥,客户端可以用证书中的公钥验证签名,确保参数确实来自服务器。
对于 RSA 密钥交换,不需要此消息。
5. ServerHelloDone
服务器发送 ServerHelloDone 消息,表明服务器端的消息发送完毕,等待客户端响应。
6. ClientKeyExchange
客户端发送 ClientKeyExchange 消息,完成密钥交换。
- 对于 RSA 密钥交换:客户端生成预主密钥(Pre-Master Secret,48 字节),用服务器的公钥加密后发送
- 对于 ECDHE 密钥交换:客户端生成临时密钥对,发送自己的临时公钥
7. ChangeCipherSpec
客户端发送 ChangeCipherSpec 消息,指示后续消息将使用协商好的加密参数和密钥进行保护。
8. Finished
客户端发送 Finished 消息,验证握手过程是否成功。此消息包含:
- 对之前所有握手消息的哈希值
- 使用协商好的密钥加密
服务器解密并验证此消息,确认握手未被篡改。
9. 服务器端的 ChangeCipherSpec 和 Finished
服务器同样发送 ChangeCipherSpec 和 Finished 消息,客户端验证服务器的 Finished 消息。
密钥生成
握手完成后,客户端和服务器各自计算主密钥(Master Secret)和会话密钥:
- Master Secret = PRF(Pre-Master Secret, “master secret”, Client Random + Server Random)
- 会话密钥 = PRF(Master Secret, “key expansion”, Client Random + Server Random)
会话密钥包括:
- 客户端写入密钥(加密客户端发送的数据)
- 服务器写入密钥(加密服务器发送的数据)
- 客户端写入 MAC 密钥
- 服务器写入 MAC 密钥
此后,所有应用层数据都使用这些会话密钥加密传输。
密钥交换算法
密钥交换算法是 TLS 握手的核心,决定了客户端和服务器如何协商共享密钥。
RSA 密钥交换
RSA 密钥交换是最传统的密钥交换方式:
- 客户端生成随机的预主密钥(48 字节)
- 客户端用服务器的公钥(从证书中获取)加密预主密钥
- 客户端将加密后的预主密钥发送给服务器
- 服务器用私钥解密,获得预主密钥
- 双方使用预主密钥和两个随机数计算会话密钥
RSA 密钥交换的缺点是缺乏前向安全性(Perfect Forward Secrecy,PFS)。如果服务器的私钥在将来泄露,攻击者可以解密所有历史通信,因为预主密钥是用服务器的公钥加密的,而攻击者可以获取私钥解密历史通信。
ECDHE 密钥交换
ECDHE(Elliptic Curve Diffie-Hellman Ephemeral)密钥交换提供前向安全性:
- 服务器生成临时密钥对(Ephemeral key pair),发送临时公钥
- 客户端生成临时密钥对,发送临时公钥
- 双方使用对方的临时公钥和自己的临时私钥通过椭圆曲线 Diffie-Hellman 算法计算共享密钥
- 共享密钥用于生成会话密钥
- 临时密钥对在会话结束后销毁
由于临时密钥对是临时的,即使服务器的长期私钥泄露,攻击者也无法解密历史通信,因为历史通信使用的是已经销毁的临时密钥协商的密钥。
ECDHE 相比传统的 DHE(基于有限域的 Diffie-Hellman)具有以下优势:
- 更短的密钥长度实现同等安全性
- 更快的计算速度
- 更小的消息尺寸
因此,ECDHE 是当前推荐的密钥交换算法。
TLS 1.3 的改进
TLS 1.3(RFC 8446)于 2018 年发布,相比 TLS 1.2 有重大改进,显著提升了安全性和性能。
握手延迟优化
TLS 1.3 将握手延迟从 2-RTT 减少到 1-RTT:
- 移除了 ServerKeyExchange、ServerHelloDone、ClientKeyExchange、ChangeCipherSpec 等消息
- 将密钥交换参数合并到 ServerHello 中
- 服务器在发送 ServerHello 的同时就可以发送加密的应用数据
对于建立新连接,TLS 1.3 只需要 1-RTT 即可完成握手并开始传输数据。
0-RTT 恢复
TLS 1.3 支持 0-RTT 会话恢复,允许客户端在第一次往返中就发送应用数据:
- 客户端使用之前会话的会话票据(Session Ticket)或预共享密钥(PSK)
- 客户端在 ClientHello 中携带这些信息以及应用数据
- 服务器验证后立即处理应用数据
0-RTT 的代价是缺乏前向安全性,因此只适用于非敏感数据。
移除不安全的密码套件
TLS 1.3 移除了所有不安全或过时的密码套件:
- 移除静态 RSA 密钥交换(无前向安全性)
- 移除 RC4、DES、3DES 等弱加密算法
- 移除 SHA-1、MD5 等弱哈希算法
- 移除 CBC 模式(易受攻击)
- 移除非 AEAD 密码套件(必须使用认证加密)
TLS 1.3 只保留 AEAD(Authenticated Encryption with Associated Data)密码套件,如 AES-128-GCM、AES-256-GCM、ChaCha20-Poly1305。
加密更多握手内容
TLS 1.3 加密了更多的握手消息(包括 Server Certificate、Certificate Verify 等),防止攻击者获取握手细节。这增强了隐私保护,使得攻击者难以通过分析握手消息推断通信内容。
简化的状态机
TLS 1.3 简化了状态机,移除了 ChangeCipherSpec 协议,减少了实现复杂度和潜在的漏洞。
证书验证过程
证书验证是确保通信安全的关键环节,客户端必须严格验证服务器证书。
证书链验证
证书链验证确保每个证书都由上级 CA 签发:
- 检查服务器证书的有效期(开始时间、结束时间)
- 检查服务器证书的用途(是否包含 serverAuth 扩展)
- 验证服务器证书是否由中间 CA 签发
- 验证中间 CA 证书是否由根 CA 签发
- 检查根 CA 证书是否在受信任的根证书列表中
- 检查证书的签名是否有效
- 检查证书是否被吊销
证书吊销检查
证书可能在有效期内被吊销,原因包括私钥泄露、证书信息错误等。吊销检查有两种方式:
CRL(Certificate Revocation List)
CA 定期发布证书吊销列表,包含所有被吊销证书的序列号。客户端下载 CRL 并查询证书是否在列表中。
缺点是 CRL 文件可能很大,下载和查询效率低。
OCSP(Online Certificate Status Protocol)
OCSP 允许客户端实时查询证书状态。客户端向 OCSP 服务器发送证书序列号,服务器返回证书状态(有效、吊销、未知)。
优点是响应快速,但 OCSP 服务器可能成为性能瓶颈。
OCSP Stapling
OCSP Stapling 是 OCSP 的优化方案。服务器定期向 OCSP 服务器查询证书状态,获得带签名的响应,并在 TLS 握手时将响应发送给客户端。
优点是减轻 OCSP 服务器负载,提高验证效率。
证书固定(Certificate Pinning)
证书固定是一种额外的安全措施,客户端预先保存服务器的证书或公钥哈希值,在连接时验证证书是否匹配。
固定方式包括:
- 固定服务器证书的公钥哈希(HPKP,HTTP Public Key Pinning,已废弃)
- 固定证书链中的某个证书
- 固定 CA 的证书
证书固定可以防止 CA 被攻击或签发虚假证书时的中间人攻击,但配置错误可能导致服务不可用。HPKP 已被废弃,现在推荐使用 Expect-CT 头或其他机制。
常见攻击与防御
尽管 TLS 设计为安全协议,但历史上仍发现了一些漏洞和攻击方式。
中间人攻击(MITM)
中间人攻击者拦截并可能修改客户端和服务器之间的通信。
防御措施:
- 严格验证服务器证书
- 使用 HSTS(HTTP Strict Transport Security)强制使用 HTTPS
- 检查证书的有效期、用途和吊销状态
- 使用证书固定(需谨慎)
降级攻击
攻击者迫使客户端和服务器使用不安全的协议版本或密码套件。例如,攻击者拦截 ClientHello,删除高版本的 TLS 支持,迫使双方使用 TLS 1.0 或 SSL 3.0。
防御措施:
- 使用 TLS Fallback SCSV(Signaling Cipher Suite Value)
- 服务器拒绝连接到不安全的协议版本
- TLS 1.3 在握手消息中加密协商的参数,防止降级
BEAST 攻击
BEAST(Browser Exploit Against SSL/TLS)攻击利用 CBC 模式下的加密漏洞,可以解密部分内容。
影响范围:TLS 1.0 和 SSL 3.0 的 CBC 模式密码套件。
防御措施:
- 升级到 TLS 1.1 或更高版本
- 使用 RC4(不推荐,RC4 本身有漏洞)
- 使用 1/n-1 分块记录技术
POODLE 攻击
POODLE(Padding Oracle On Downgraded Legacy Encryption)攻击利用 SSL 3.0 的 CBC 模式填充漏洞。
防御措施:
- 禁用 SSL 3.0
- 使用 TLS 1.0 或更高版本
- TLS 1.3 完全移除了 CBC 模式
Heartbleed 漏洞
Heartbleed 是 OpenSSL 的实现漏洞,攻击者可以读取服务器内存中的敏感数据(如私钥)。
影响范围:使用 OpenSSL 1.0.1 到 1.0.1f 的版本。
防御措施:
- 升级 OpenSSL 到修复版本
- 吊销并重新签发所有证书
- 更换所有密钥
其他攻击
- CRIME:利用压缩的侧信道攻击
- TIME:利用时间差异的侧信道攻击
- Lucky 13:利用 MAC 验证时间差异的攻击
防御措施包括禁用压缩、使用恒定时间算法等。
实践建议
推荐密码套件
对于 TLS 1.2,推荐以下密码套件(按优先级排序):
1 | |
对于 TLS 1.3,密码套件简化为:
1 | |
禁用不安全的协议和算法
- 禁用 SSL 2.0、SSL 3.0
- 禁用 TLS 1.0、TLS 1.1(除非必须兼容旧客户端)
- 禁用 RC4、DES、3DES
- 禁用 SHA-1、MD5
- 禁用静态 RSA 密钥交换
- 禁用 CBC 模式
配置 HSTS
HSTS(HTTP Strict Transport Security)强制浏览器只通过 HTTPS 连接,防止降级攻击和 SSL Stripping 攻击。
配置示例:
1 | |
参数说明:
- max-age:HSTS 策略的有效期(秒)
- includeSubDomains:策略应用于所有子域名
- preload:加入 HSTS Preload 列表(浏览器内置)
启用 OCSP Stapling
OCSP Stapling 提高证书验证效率,减少 OCSP 服务器负载。
Nginx 配置示例:
1 | |
Apache 配置示例:
1 | |
使用现代 TLS 配置
推荐使用 Mozilla SSL Configuration Generator 生成安全的 TLS 配置:
- Old:兼容性最好,安全性较低
- Intermediate:平衡兼容性和安全性(推荐)
- Modern:最高安全性,兼容性较差
定期更新和监控
- 定期更新服务器软件和 OpenSSL 版本
- 监控证书有效期,及时续期
- 使用自动化工具(如 Let’s Encrypt)管理证书
- 定期进行安全审计和渗透测试
测试 TLS 配置
使用以下工具测试 TLS 配置的安全性:
- SSL Labs Server Test:https://www.ssllabs.com/ssltest/
- TestSSL.sh:开源命令行工具
- Mozilla Observatory:https://observatory.mozilla.org/
总结
TLS 是现代互联网安全通信的基石,综合运用了对称加密、非对称加密、哈希函数、数字签名和数字证书等多种密码学技术。理解 TLS 握手过程、密钥交换算法、证书验证机制以及常见攻击方式,对于配置和维护安全的 TLS 服务至关重要。
TLS 1.3 的引入显著提升了安全性和性能,但许多旧系统仍使用 TLS 1.2 或更早版本。在实际应用中,应根据兼容性和安全性需求选择合适的协议版本和密码套件,并定期更新和测试配置。
随着量子计算的发展,后量子密码学(Post-Quantum Cryptography)将成为未来 TLS 的重要研究方向。目前,IETF 正在制定后量子 TLS 标准,以应对量子计算对现有加密算法的威胁。


