密码学 E02:后量子 KEM、ML-KEM、ML-DSA 与混合握手
有人说:“换成后量子算法以后,把 ML-DSA 签名加进握手,就能替代密钥交换。”这是把两件不同操作放在一个盒子里:ML-KEM 用于建立双方一致的秘密,ML-DSA 用于证明特定消息由签名密钥持有者授权。KEM 共享秘密匹配也不会自动认证发送密文的一端;签名验真也不会自动证明自己与另一端共享了对称记录密钥。旧的量子风险解释应具体指出 RSA/ECDH 的困难假设面临哪类威胁,不能因为“后量子”三个字就宣称工程已经抵抗了未来所有攻击。
KEM 的四个输入输出
受信任的接收方发布 ML-KEM 公钥,保留私钥。发送方拿到已正确绑定身份的公钥后执行封装:输入公钥与随机源,输出可发送的密文 cipherText 以及自己的共享秘密 sharedSecret;接收方对同一密文用私钥解封装,得到相同共享秘密。发错私钥或改封装密文时,许多 KEM 采用隐式拒绝:返回不同的秘密而非清晰抛出“认证失败”。随后必须在有身份约束的协议里通过 transcript/Finished 或应用认证发现双方秘密不一致,不能把“函数没有报错”写成“双方已认证”。
ML-DSA 则取私钥与指定消息字节生成签名,任意拿到正确公钥的人对那些字节验签;它自己不产生双方会话秘密。两套密钥用途和泄漏影响要分别管理。一个“混合”握手可能将经典 X25519 的 32 字节共享秘密与 ML-KEM 的 32 字节结果通过指定格式和 HKDF 结合,保证双方按同一 transcript、顺序和身份规则处理;真实协议还须指定算法协商、降级防护、证书、重试和 KEM 密文绑定,不能把简单拼接函数称为完整 TLS。
1 | |
examples/cryptography/E02_post_quantum.mjs 使用冻结的成熟 JS ML-KEM-768/ML-DSA-65 真原语,先核对共享秘密相等、错私钥和改密文各得到不同的秘密;真签名对原消息验真、改消息不通过。另用 Node 真 X25519 + hkdfSync,在这份本地自定格式中混合两种秘密和公开的合成 transcript,让两端导出一致 32 字节密钥:
先按仓库内 examples/cryptography/README.md 完成环境准备;以下命令从仓库根目录执行。
1 | |
原语正反例 1 项测试通过,tls_hybrid_handshake_executed=false。还没有将 FIPS 正式 KAT 每字节核对,没有抓实际 TLS 混合握手或真实 PKI 签名,也没有断言此库取得任何 NIST 认证。不得用“库可计算”替代“特定浏览器、服务器、fork 已启用并正确协商”,也不得把 ML-KEM 的密码学保密目标直接升级成真实订单交付。
练习及答案
画图题: 发送方 A 错把攻击者的 ML-KEM 公钥当服务公钥,解封装操作可成功发生在哪里?若将服务身份验证整段删掉,但双方 KEM 共享秘密一致,攻击者会怎样插进来?
答案: 发送方封装到攻击者公钥,攻击者用自己私钥解封并共享这个秘密;真实服务的私钥无法解出相同秘密。能与某个公钥算出相同秘密只证明你与该密钥的持有人共享,并未验证它是预期服务。需要将公钥/握手 transcript 绑定到可信的服务身份,否则中间人分别协商两组秘密。
实验变更题: 翻转 cipherText[7] 但不更换接收私钥,程序为何不能以“没有抛异常”判通过?另改 ML-DSA 消息尾字节但仍使用原签名,哪项操作应失败?
答案: 解封装可能返回不同共享秘密,双方若用它派生记录密钥,密钥确认或后续认证应失败;不能以返回值存在为成功标准。ML-DSA 对改后消息的公开验签应失败,正确 KEM secret 不替签名核对消息字节。
资料与导航
- FIPS 203 ML-KEM · FIPS 204 ML-DSA · RFC 5869 HKDF。本地拼接不是发布版 TLS 混合握手规范。
- 10:DH 与中间人 · 11:HKDF · 15:TLS 1.3。






