密码学基础回顾:TLS 背后的那些数学魔术

说实话,很多人觉得密码学离自己很远。但我跟你说,每次你打开一个 HTTPS 网站,你就在跟一堆数学函数打交道。TLS 握手说白了就是把这些密码学原语编排成一场精密的舞蹈。这一章我们就把舞台上的主角们认一遍。

对称加密:一把钥匙开一把锁

对称加密,你想想看,发送方和接收方用的是同一个密钥。加密和解密就像用同一把钥匙开同一把锁。我最早做安全协议时,总觉得对称加密“不够酷”,后来被现实狠狠教育了——性能才是王道。

TLS 1.3 里主要留了两个对称加密算法:AES 和 ChaCha20。为什么是它们俩?

特性AES-GCMChaCha20-Poly1305
硬件加速有(AES-NI 指令集)无,但纯软件快
性能(x86)极快(有硬件)接近,无硬件时更快
性能(ARM/移动端)中优
安全性标准选择抗侧信道强
TLS 默认Chrome/Firefox 首选手机端常用

我个人习惯:在嵌入式设备或者没有 AES-NI 的 ARM 平台上,我会优先推荐 ChaCha20。有次我在一个老旧的路由器上做 TLS 优化,AES 慢到握手都超时,换成 ChaCha20 后瞬间流畅。嗯,这就是实战。

小提醒:对称加密的密钥怎么安全地分发给对方?这正是非对称加密要解决的问题。别急,下面就说。

非对称加密:公开锁箱,私有钥匙

非对称加密用了两个密钥:公钥公开,私钥保密。你拿公钥锁上数据,只有私钥能打开。TLS 里非对称加密负责密钥交换和身份认证。

讲讲三巨头:

RSA

RSA 老当益壮。它基于大整数分解难题。我入行那会儿,TLS 基本全是 RSA 签名 + RSA 密钥交换。但 RSA 有两个问题:

  • 密钥太大(2048 位起步),计算慢
  • 不能提供前向安全性——如果私钥泄露,之前所有通信记录都能被解密

所以现在 TLS 1.3 已经禁止 RSA 密钥交换了,只保留 RSA 签名做证书验证。

ECDH

ECDH(椭圆曲线 Diffie-Hellman)是当今的主角。它用更短的密钥提供同等安全强度(256 位 ECC ≈ 3072 位 RSA)。更关键的是,每次握手都生成临时密钥对,握手结束就扔掉。这就是前向安全性——就算你今天拿到了我服务器私钥,也解不开昨天录的流量。

曾经踩过的坑:ECDH 曲线选择要小心。我曾经在生产环境误配了 secp224r1(不常用),结果某个老旧客户端直接握手失败。业界标配是 X25519(Curve25519),兼容性最好,性能也棒。

Ed25519

Ed25519 是基于椭圆曲线的签名算法。速度比 RSA 快一个数量级,签名体积小(64 字节 vs RSA 256 字节)。TLS 1.3 把它列入了可选签名方案。我个人非常看好它,尤其是内部微服务间通信,用 Ed25519 签名能显著降低握手延迟。

哈希函数:给数据打指纹

哈希函数把任意长度数据映射成固定长度的摘要。TLS 里哈希主要用在两个地方:消息完整性校验和证书签名摘要。

TLS 1.3 只认两个哈希族:SHA-256 和 SHA-384。SHA-1 已经被彻底淘汰,原因你应该知道——Google 和瑞昱在 2017 年就演示了碰撞攻击。我之前接手过一个老系统,证书链里还藏着 SHA-1 签名,直接导致浏览器警告。清理了一整天才搞定。

算法输出长度TLS 用途
SHA-256256 位HKDF 派生、证书摘要、签名摘要
SHA-384384 位高安全场景(如 256 位 AES-GCM 搭配)

消息认证码(HMAC):既防篡改又防假冒

光靠哈希不够。如果有人同时篡改了数据和新算的哈希值呢?HMAC 引入了密钥,确保只有知道密钥的人才能生成正确的校验值。

TLS 里 HMAC 用得最多的地方是 HKDF(基于 HMAC 的密钥派生函数)。握手过程中所有对称密钥都是从预主密钥通过 HMAC 一步步“榨”出来的。我调试过一例奇怪的证书握手失败,最后发现是 HMAC 计算时密钥长度没对齐——小小细节,能让你查三天。

一句话总结本轮:对称加密负责数据传输时的高速加解密;非对称加密负责握手时的密钥交换和身份认证;哈希做完整性校验;HMAC 在密钥派生和消息认证中防止伪造。四者缺一不可。
TLS 中的密码学组件协作关系 TLS 握手 对称加密 AES / ChaCha20 非对称加密 RSA / ECDH / Ed25519 哈希函数 SHA-256 / SHA-384 消息认证码 HMAC (HKDF) 数据加密 密钥交换 / 签名 完整性校验 密钥派生 (HKDF) TLS 先靠非对称加密交换临时密钥,再用 HMAC 衍生会话密钥, 最后用对称加密保护实际数据,期间哈希全程提供完整性保障。

它们是怎么串起来的?

TLS 1.3 握手流程非常紧凑。我画个简单路径:

  1. 第一步:客户端发 ClientHello,列出支持的对称加密套件(比如 AES-GCM 或 ChaCha20)、密钥交换曲线(X25519)、签名算法(Ed25519 或 RSA)
  2. 第二步:服务器发 ServerHello,选定一组参数,同时发送自己的临时 ECDH 公钥和证书(证书里有 RSA 或 Ed25519 签名)
  3. 第三步:客户端验证证书签名(用哈希+公钥解密对比摘要),然后计算自己的 ECDH 私钥,得到预主密钥
  4. 第四步:双方用 HKDF(基于 HMAC+SHA256)从预主密钥派生出对称密钥
  5. 第五步:后续所有应用数据都用 AES 或 ChaCha20 加密传输,每条消息带 HMAC 标签(实际是 GCM/Poly1305 的认证标签)
核心结论:没有非对称加密,对称密钥就传不过去;没有哈希,证书签名就验不了真伪;没有 HMAC,密钥派生的安全性就无从保证;没有对称加密,数据传输就慢得无法接受。每一种算法都卡在 TLS 的不同环节,少一个就崩不了。

我当年第一次把 TLS 抓包分析时,看到那一串串二进制直接懵了。但当你理解每个字节背后是哪个算法在干活,整个协议就像一张织好的网——清晰、优雅、坚韧。这就是密码学的力量。