2. 密码学原语速览
TLS 不是某一种加密算法,而是一套把多种密码学原语按明确分工组装起来的协议。理解 TLS 配置,第一步不是背算法名字,而是弄清每种原语“解决什么问题、不解决什么问题、在握手或记录层出现在哪个位置”。下面按数据流顺序梳理这些原语的角色与边界。
一、先分清两类目标:机密性与完整性
密码学原语大致服务于两个目标:机密性(别人看不到内容)和完整性/真实性(内容没被改、来源可信)。对称加密、非对称加密主要提供机密性;哈希、MAC、数字签名主要提供完整性与认证;AEAD 则把机密性和完整性合并到一次操作里。密钥交换本身不加密业务数据,它的任务是让双方安全地协商出后续要用的对称密钥。
二、对称加密:TLS 记录层的主力
对称加密使用同一把密钥加解密,速度快,适合保护大量应用数据。TLS 1.3 中记录层实际使用的对称算法只有 AES-128-GCM、AES-256-GCM、ChaCha20-Poly1305 三种,它们都是 AEAD。TLS 1.2 还允许 AES-CBC 等非 AEAD 模式,但 CBC 容易因填充处理不当引入问题,现代配置应优先 AEAD。
对称加密的边界在于:它假设双方已经共享密钥。密钥怎么来、怎么保证没被中间人替换,不是对称加密自己能解决的,这要靠密钥交换和认证。
三、非对称加密与密钥交换:解决“密钥怎么安全到达”
非对称加密使用公钥/私钥对。公钥可公开,私钥保密。它的计算比对称加密慢得多,因此 TLS 不用它来加密业务数据,而是用于密钥交换和身份认证。
密钥交换的典型方式是 ECDHE(椭圆曲线临时 Diffie-Hellman)。双方各自生成临时密钥对,交换公钥后独立计算出同一个共享秘密,再用 HKDF 派生出握手密钥和应用流量密钥。ECDHE 的关键优势是前向保密:即使服务器长期私钥日后泄露,攻击者也无法解密之前录下的会话,因为每次会话的临时私钥已经销毁。
非对称加密的边界是:它不直接保护应用数据,只用于建立密钥和验证身份;而且它依赖公钥的真实性,否则中间人可以替换公钥。
四、哈希:把任意长度数据压成固定长度摘要
哈希函数把任意长度输入映射为固定长度输出,且不可逆、抗碰撞。TLS 中哈希不单独用于加密,而是作为构造其他原语的组件:HMAC 内部用哈希,HKDF 用哈希做密钥派生,数字签名先对消息做哈希再签名,证书指纹也是哈希。
TLS 1.3 允许的哈希是 SHA-256 和 SHA-384。MD5、SHA-1 已被认为不适合继续用于安全场景。哈希的边界是:它只保证“改过就能发现”,不提供机密性,也不证明“是谁发的”。
五、MAC 与 AEAD:完整性和机密性的两种组合方式
MAC(消息认证码)用共享密钥对消息计算认证标签,接收方用同一密钥验证。HMAC 是最常见的构造。在 TLS 1.2 的 AES-CBC 套件中,常见做法是先加密再对密文计算 HMAC,即 Encrypt-then-MAC。这种方式需要分别处理加密和 MAC,容易在实现中出错。
AEAD(带关联数据的认证加密)把加密和认证合并为一个原语,一次调用同时输出密文和认证标签,并允许把不加密的附加数据(AAD)也纳入认证。TLS 1.3 记录层只使用 AEAD,AAD 通常包含记录头等元数据。AEAD 的边界是:它保证密文和 AAD 未被篡改,但不负责密钥协商,也不证明对端身份。
六、数字签名:证明“是谁发的”
数字签名用私钥对消息(通常是消息的哈希)签名,任何人用对应公钥验证。它提供身份认证和不可否认性,但不提供机密性——签名不隐藏消息内容。TLS 中数字签名主要用于:服务器在握手时用证书私钥签名,证明自己持有证书对应的私钥;客户端在双向认证时也可能签名。
数字签名的边界是:它依赖公钥的真实性。如果公钥被中间人替换,签名验证就会通过错误的公钥进行,因此需要证书链和信任锚来绑定公钥与身份。
七、各原语在 TLS 中的位置与边界对照
| 原语 | 主要作用 | TLS 中的位置 | 不负责什么 |
|---|---|---|---|
| 对称加密 | 保护应用数据机密性 | 记录层 | 密钥协商、身份认证 |
| 非对称加密 | 签名、验证、部分密钥交换 | 握手层 | 批量数据加密 |
| 哈希 | 摘要、派生、签名前置 | 握手与记录层内部 | 机密性、身份认证 |
| MAC | 完整性 + 共享密钥认证 | TLS 1.2 CBC 套件 | 机密性、对端身份 |
| AEAD | 机密性 + 完整性一次完成 | TLS 1.3 记录层 | 密钥协商、身份认证 |
| 密钥交换 | 协商共享密钥 | 握手层 | 数据加密、身份认证 |
| 数字签名 | 身份认证、不可否认 | 握手层 | 机密性、密钥协商 |
八、实际配置中的判断依据
在配置 TLS 时,可以用以下问题快速判断原语选择是否合理:
- 记录层是否只使用 AEAD?如果还在用 AES-CBC,应优先迁移到 AES-GCM 或 ChaCha20-Poly1305。
- 密钥交换是否使用 ECDHE?如果使用 RSA 密钥交换,则没有前向保密,应改为 ECDHE。
- 哈希是否至少为 SHA-256?MD5、SHA-1 不应继续用于签名和证书。
- 签名算法是否与证书公钥匹配?例如 ECDSA 证书应使用 ECDSA 签名,RSA 证书使用 RSA-PSS 或 RSA-PKCS#1 v1.5。
- 是否启用了双向认证?如果需要客户端证书,则客户端也要用私钥签名。