跳到主要内容
加密解密2026-10-04Begin4 分钟阅读

ML-KEM 入门:Kyber 是怎么进到你的 TLS 握手里的

从「加密」到「封装」:KEM 是换个姿势送密钥

TLS 要建立对称会话密钥,绕不开一个问题:双方怎么在公开信道上商量出同一个秘密?经典答案有两代——RSA 时代直接「用对方公钥加密预主密钥」,ECDH 时代改为「双方各出临时公钥,做 Diffie-Hellman 搬运算」。两代的共同点:安全性都压在「大数分解 / 椭尔曲线离散对数」这类经典难题上,而这些问题在 Shor 算法面前不堪一击(背景见上一篇)。

ML-KEM 属于第三代答案:密钥封装机制(Key Encapsulation Mechanism)。流程是三步:

  1. 密钥生成:产生公钥 + 私钥(和以前一样)
  2. 封装:任何人拿公钥执行封装算法,输出一个封装体(密文)和一个新随机的共享密钥
  3. 解封装:私钥持有者从封装体里恢复出同一个共享密钥

和 RSA-OAEP「先想好密钥再加密发过去」的区别在谁掌握密钥的诞生:KEM 里共享密钥是封装算法内部派生的,你永远不需要自己选一个密钥再想办法送出去——这消除了「密钥本身随机性不足」的一整类工程事故。

Kyber 的来历:一场八年竞赛的胜者

ML-KEM 的前身 Kyber 出自 NIST 2016 年启动的后量子密码标准化竞赛,2022 年 7 月被选定为 KEM 方向的标准基础,2024 年 8 月正式发布为 FIPS 203。名字里的 ML 指模格(Module Lattice)——安全性的数学地基从整数分解换成了格上的噪音求解问题:把一个秘密向量混进带噪音的线性方程组里,量子算法目前对它没有任何结构性优势。不需要吃透格数学也能记住它的工程特征:快(软件实现与 ECDH 同量级)、密钥大(比 X25519 大一个数量级)、抗量子。

三档参数与尺寸:工程痛点的根源

参数组等效强度公钥封装体对照 X25519
ML-KEM-512AES-128800 B768 B32 B
ML-KEM-768AES-1921,184 B1,088 B32 B
ML-KEM-1024AES-2561,568 B1,568 B32 B

TLS 目前主流采用 ML-KEM-768。公钥加封装体合计约 2.3KB——是 X25519 的三十多倍。这个数字决定了迁移的几乎所有工程摩擦(见下)。

混合握手:不是过渡方案,是安全设计

浏览器和服务器现在跑的不是「纯 ML-KEM」,而是 X25519MLKEM768 混合组:

  1. ClientHello 的 key_share 里同时携带 X25519 公钥(32B)和 ML-KEM-768 公钥(1,184B)
  2. 服务端对两个算法分别完成密钥交换,得到两个共享密钥
  3. TLS 1.3 的密钥调度(基于 HKDF)把两个秘密拼接后派生会话密钥

关键性质:攻击者必须同时破掉格问题和椭圆曲线问题才能恢复会话——经典计算机被量子攻破的场景里 ML-KEM 兜底,ML-KEM 将来被发现弱点则 X25519 兜底。「混合」常被误读为过渡期妥协,实际上它是双保险结构,短期内不会退役。

ClientHello 膨胀的中间盒坑

多出 1.1KB 意味着 ClientHello 从单个 TCP 段溢出到第二个段。Chrome 在灰度 X25519Kyber768(混合组的前身)时真的踩过:部分企业防火墙对超大或「看不懂」的握手包直接掐断连接。所以部署顺序有讲究——先在 CDN/入口层灰度观察握手成功率,再全量。这也是 迁移 checklist 把「灰度 + 握手成功率监控」列为必做项的原因。

怎么开(2026-10 现状)

  • 浏览器侧:Chrome / Firefox 已默认支持,无需配置
  • OpenSSL 3.5+:内置 X25519MLKEM768 分组
  • nginx(链接 OpenSSL 3.5+):ssl_ecdh_curve X25519MLKEM768:X25519;(保留 X25519 作回退)
  • CDN:Cloudflare 等已开放开关,托管在 CDN 后的源站升级收益有限——协商发生在边缘
  • 验证方式:浏览器开发者工具的 Security 面板看密钥交换组名,或用支持混合握手的 openssl s_client 检查协商结果;你的证书本身(证书解码器可见)暂时还是 RSA/ECDSA——证书体系迁 PQC 是另一条更慢的时间线(签名要等 ML-DSA 生态)

实现注记 / Implementer's note

站里暂时没有 PQC 在线工具,原因很具体:WebCrypto 至今没有 ML-KEM 接口(crypto.subtle 的清单还是 RSA/ECDH/AES 那一套),想在浏览器跑 ML-KEM 只能上 liboqs 的 wasm 编译,包体积按 MB 计——对「打开就用的在线工具」是体验灾难。写 RSA 工具时我留了个对照点:RSA-OAEP 加密 32 字节密钥要付出数百字节的膨胀,ML-KEM-768 封装同样量级的秘密要 1,088 字节——封装体尺寸是 KEM 与 DH 系最直观的差异,等 WebCrypto 原生支持后我会把 ML-KEM 加进工具矩阵,让这个对照可玩。

相关阅读