大家好,我是Tony Bai。
【导读】
后量子迁移的时间表,在 2026 年初被彻底改写:业界共识是,必须在 2029 年前完成迁移。只剩三年了!Go 前密码学负责人 Filippo Valsorda 为此更新了业界传承十余年的“密码学正确答案”清单。结论很清晰:对称密码基本不用慌,但所有非对称算法的答案都变了。从密钥交换到数字签名,从 TLS 库到备份工具,这份清单直接告诉你该选什么、该扔什么。
【文章要点】
-
“密码学正确答案”是一个传统:Colin Percival(2009)→ Thomas Ptacek(2015)→ Latacora(2018、2024)→ Filippo(2026)。 -
时间线巨变:后量子迁移的共识截止时间是 2029 年。 -
对称密码不用恐慌:Grover 算法实际上不构成威胁,256 位密钥即可,不必过度纠结。 -
非对称密码必须全面更换:密钥交换用 X25519+ML-KEM-768,签名用 ML-DSA-44,加密用 HPKE(X-Wing)或 age。 -
密钥交换最紧迫:因为“先存储、后解密”(harvest-now-decrypt-later)攻击,非 PQ 方案是现实存在的风险。 -
工程层面的新增建议:用内存安全语言,并让最强的 LLM 帮你审查代码;尽量少用非对称签名。 -
工具选型:TLS 库不推荐 OpenSSL,推荐 rustls、Go crypto/tls、BoringSSL、AWS-LC、s2n-tls;备份用 restic。
2029,只剩三年
“密码学正确答案”(Cryptographic Right Answers),是密码学圈一个延续了十几年的传统。
2009 年,Colin Percival 开了头;2015 年,Thomas Ptacek 接力;2018 年和 2024 年,Latacora 又先后更新。每一版,都是写给不想成为密码学家、只想把系统做对的开发者的一份“抄作业指南”。
按理说,2024 年刚更新过,不该这么快再来一版。
但Filippo 说:这次变化实在太大了。
原因只有一个:后量子迁移的时间线,在 2026 年初发生了剧烈变化。现在,业界已经形成共识,迁移必须在 2029 年前完成。
2029 年!我们只有三年!
好消息是:对称密码学基本没事,因为 Grover 算法其实不重要。
坏消息是:所有非对称算法的答案,相比 2018 年全变了,相比 2024 年,大部分也变了。
此外,2026 年还有另一个重要变化:LLM 现在非常擅长发现 Bug。“让你买得起的最强模型帮你审查一遍”,现在已经正式成为一条“密码学正确答案”,和老牌经典“使用内存安全语言”并列。
先看结论:一张速查表
赶时间?直接抄这个:
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 密钥交换 | X25519+ML-KEM-768
|
| 非对称加密 | HPKE(MLKEM768-X25519,即 X-Wing)
|
| 非对称签名 | ML-DSA-44 |
|
|
|
|
|
|
加粗的三行,就是这次“大换血”的核心。
先稳住:这些部分基本没变
对称密码:别慌
先说一句让人安心的:Grover 不重要,128 位暴力破解并不存在。
所以,对称密钥长度这件事,作者的建议是“别纠结”。如果非要选,就选 256 位,它还有一个额外好处:能排除多目标攻击。
但也不要因此去强行修改 TLS 库的默认密码套件。比如推荐的 Cobblestone 使用的是 128 位密钥,这没问题,因为它有针对多目标攻击的细致分析。
加密数据:别自己管 nonce
本地加密时,你需要一个 AEAD,并且最好不用操心 nonce 计数。所以应选择至少 128 位的随机 nonce。
具体推荐:
-
XAES-256-GCM:标准 KDF 加 AES-GCM 的高效组合,封装成扩展 nonce 的 AEAD。 -
XChaCha20Poly1305:同样支持随机 nonce。
普通的 AES-GCM 和 ChaCha20Poly1305 配随机 nonce,只有在你确定同一密钥下加密的消息不超过十亿条时才算可以。
还有一个很多人踩的坑:大消息处理。 不要把一个超大消息一次性丢给 AEAD,否则解密时你可能被迫在认证通过前就处理或存储明文。更不要使用未认证的流密码。
正确做法是使用 STREAM(注意,它不是流密码,而是在数据流上使用 AEAD 的方法)。目前可选方案很多,Tink、libsodium、AWS Encryption SDK、FLOE、age 都有各自的实现,却没有一个公认的标准答案。作者推荐的是 Cobblestone-128,一种源自 TLS 的 STREAM 变体。
Filippo 披露:XAES-256-GCM 和 Cobblestone 都是他自己的设计,但已被外部广泛采用。
HMAC、哈希、随机数:老朋友依旧靠谱
-
对称“签名”:2009 年到 2024 年,历任作者的答案都是 HMAC,今天依然是 HMAC-SHA-256。一个细节:要认证的是原样字节串,而不是需要重新计算的结构化数据,否则容易踩进规范化和解析器不一致的坑。 -
哈希:SHA-2 仍然够用。最好的选择依旧是 SHA-512/256,它不受长度扩展攻击影响。需要同时哈希多个对象时(例如一行中的多列),请使用 SequenceHash,不要自己拼接。 -
随机 ID:32 个随机字节。UUIDv4 之类只有约 128 位,通常也够用,除非你需要超过 2^48 个唯一值。请使用操作系统的 CSPRNG。
密码处理:先想想要不要密码
推荐 Argon2id 或 scrypt。作者去掉了 bcrypt,原因是它的 72 字节截断会出问题。
参数方面,作者建议无视 RFC 9106,改用:
Argon2id: m=64 MiB, t=2, p=1
scrypt: N=2^16, r=8, p=1
两者内存占用相同,但 scrypt 约多花 1.5 倍 CPU 时间、少花 1/4 GPU 时间,所以更推荐 Argon2id。
不过比选算法更重要的问题是:你真的需要密码吗?能不能改用抗钓鱼的 passkey?或者邮件魔法链接加 SSO(OIDC,而不是 SAML)?
另外,2026 年的 passkey 还不是后量子的。作者认为这基本没问题:量子攻击者最多只能在拿到某个网站的数据库或截获一次登录后,登录那个特定网站。
必须换:三个“大换血”领域
密钥交换:X25519+ML-KEM-768
历代答案:
Percival 2009:2048 位 Group #14,生成元为 2
Ptacek 2015:大概还是 DH-2048,或 NaCl
Latacora 2018:大概什么都不用,或 Curve25519
Latacora 2024:X25519+ML-KEM-768
Filippo 2026:X25519+ML-KEM-768(在安全的标准协议里)
作者的态度很明确:非 PQ 方案,是一个现实、紧迫的风险,原因是“先存储、后解密”攻击。
具体怎么选?不要自己设计协议,直接选:
-
TLS: X25519MLKEM768 -
SSH: mlkem768x25519-sha256 -
HPKE 和 age: MLKEM768-X25519
有一条很有分量的建议:如果选择或实现混合方案,意味着你要在经典的非 PQ 密钥交换上多停留哪怕一个月,那就直接上纯 ML-KEM-768。
其他 PQ 方案呢?要么不实用(HQC-KEM、FrodoKEM),要么不实用而且已经被攻破(Classic McEliece)。
作者给的避坑规则很简单:名字里没有 ML-KEM 或 X-Wing 的,一律不要用。
非对称加密:HPKE 登场
历代答案:
Percival 2009:RSAES-OAEP
Ptacek 2015:NaCl
Latacora 2018:NaCl/libsodium(box)
Latacora 2024:很棘手,等成熟的 PQ 方案
Filippo 2026:HPKE(MLKEM768-X25519 即 X-Wing,HKDF-SHA256,AES-128-GCM),或带 PQ 密钥的 age
这是近几年改进最大的答案之一。我们终于有了一个混合加密的标准:HPKE。
注:这里的“混合”是指“非对称 + 对称”,不是“经典 + 后量子”。名字重载,没办法。
需要更高层封装、多接收者或命令行工具?用 age,其新的 age1pq 前缀密钥基于 MLKEM768-X25519。YubiKey 和 Secure Enclave 等插件也在陆续支持 PQ。
不过,作者也吐槽了一句:PQ HPKE KEM 至今仍然只是草案,而且还被分散在四份草案里,以至于他不得不另外写了一个库 filippo.io/hpke-pq。好在作者们已经保证不再改动线上格式,各家密码库也都已发布实现,所以可以放心使用。
避开:RSA、NaCl 的 box、OpenPGP,以及加密邮件。
数字签名:ML-DSA-44
历代答案:
Percival 2009:RSASSA-PSS
Ptacek 2015:NaCl、Ed25519 或 RFC 6979
Latacora 2018:NaCl 或 Ed25519
Latacora 2024:短期用 Ed25519,否则 Ed25519+ML-DSA-65
Filippo 2026:ML-DSA-44
作者坦言,2026 年 1 月时他还会建议“再观望一下”,直到进展开始加速。签名也必须迁移到 PQ 了。
具体建议:
-
直接用 ML-DSA-44。 -
需要预哈希时,用 “external-μ(Mu)” 签名,不用 HashML-DSA。 -
密钥只存 32 字节种子。
为什么不推荐混合签名或“组合签名”?作者认为,混合认证比混合密钥交换更复杂、用处也更小。要么你已经有密钥轮换策略,可以在经典算法被破时轮换回去;要么你的时间跨度太长,应当默认量子计算机迟早会攻破经典那一半。
为什么 ML-KEM 选 768,签名却选 -44?因为 ML-DSA-44 对应 NIST 类别 2,已经在 128 位安全级别之上有一定余量。
唯一的例外是 SSH 密钥:OpenSSH 10.6 选择了 ssh-mldsa44-ed25519。作者认为这是个错误,但你要是“偏离主流”,同样会是错误。
还有一条被很多人忽略的提醒:非对称签名被滥用了,而且现在已经不便宜。能用 HMAC 就用 HMAC;能用随机会话令牌替代签名 JWT 的,就换掉。如果是要对外公开承诺,可以考虑透明日志。
避开:RSA、ECDSA、Ed25519 等所有非 PQ 选项,有状态签名(LMS/XMSS),HashML-DSA,ML-DSA 的“半展开密钥”,组合签名,OpenPGP。
落地选型:TLS 库和备份
作者可能最“不实用”的建议:别用 OpenSSL
原文坦言,不推荐 OpenSSL 大概是自己最不实用的建议。但他指出,OpenSSL 多年来持续做出令人费解、有问题的决定。pyca/cryptography 的作者在一篇长文中,将他们对 OpenSSL 的体验概括为“多年来呈负面走势”。HAProxy 与 curl 也有类似批评。
作者推荐:
-
rustls 或 Go 的 crypto/tls:内存安全。 -
必须用 C:BoringSSL 或 AWS-LC,后者有版本化发布。 -
s2n-tls:不需要 libssl 兼容时是个有趣的选择。
披露:作者本人是 Go crypto/tls 的维护者之一。
无论用哪个,都要确认它优先选择 X25519MLKEM768,这需要 TLS 1.3。云负载均衡器可能需要你手动选择 PQ 安全策略;RHEL 9 及衍生版本则需要主动开启。
原文还列出了一批“在核心职责上出过问题”的 TLS 库,并附了 CVE 编号,包括 GnuTLS、Mbed TLS、wolfSSL 和 Botan。这些细节建议读者直接查阅原文脚注。
PKI 方面:
-
两端可控的应用:可以自建 ML-DSA-44 的 X.509 证书,自签或私有根。 -
网站:接入一个主流、支持良好的 ACME 客户端,并保持更新。Merkle Tree Certificates 将于 2027 年推出,你需要为被纳入这次过渡做好准备。
备份:restic 代替 Tarsnap
历代作者的答案一直都是 Tarsnap,这次变了:restic + 一个足够长的随机密码。
原因是 restic 完全使用对称密码,不怕量子计算机。而 Tarsnap 的非对称层全是 RSA。作者表示“感觉像在背叛前辈”,不过从技术上讲,真正会被破的只是低权限密钥:写入专用密钥可以解密归档,只读密钥可以伪造归档。但面对即将到来的量子计算机,这仍然是个隐患。
一张图看懂选型
再看一眼迁移紧迫性的逻辑:
这正是密钥交换要最先迁移的原因:加密流量一旦被存下来,就等于把未来交给了攻击者。
今天就能做的三件事
如果你读完只想行动,那就做这三件事:
-
检查你的 TLS 栈:确认它启用了 X25519MLKEM768(需要 TLS 1.3),OpenSSL 至少要 3.5。 -
盘点你的签名:哪些真的需要非对称签名?能换成 HMAC 或随机令牌的先换掉,其余的规划迁移到 ML-DSA-44。 -
审计你的代码:用内存安全语言(比如 Rust、Go 等),再让最强的 LLM 审查一遍。
2029 年不远了。对称密码已经替你扛住了量子时代的一半,剩下那一半,是时候动手了。
原文地址:Filippo Valsorda,《(Post-Quantum) Cryptographic Right Answers》,https://words.filippo.io/right-answers/
如果本文对你有所帮助,请帮忙点赞、推荐和转发
!
点击下面标题,阅读更多干货!
- Go 1.27 中值得关注的几个变化:从泛型方法终成正果、encoding/json/v2 转正到后量子安全全面落地
- RSA 将死?Let's Encrypt 押注 MTCs 迎战后量子时代
- Go 2025 密码学年度报告:后量子时代的防御与 FIPS 的“纯 Go”革命
- 未雨绸缪:Go开发者需要了解的后量子密码学与实现现状
- Go 官方密码学原则:为什么 Go 的 Crypto 库难以被“用错”?
- Go开发者的密码学导航:crypto库使用指南
- Go 密码学维护者放大招:把 Passkey 存成一行字符串,还顺手为 Go 1.28 写好了 API
🔥 还在为写 Agent 框架频频死循环、上下文爆炸而束手无策?我的新专栏 《从0 开始构建 Agent Harness》 将带你:
-
抛弃臃肿框架,回归“驾驭工程 (Harness Engineering)”的第一性原理 -
用 Go 语言手写 ReAct 循环、并发拦截与上下文压缩引擎等,复刻极简OpenClaw -
构建坚不可摧的 Safety Middleware 与飞书人工审批防线 -
在底层实现 Token 成本审计、链路追踪与自动化跑分评估 -
从“调包侠”进化为掌控大模型边界的“AI 操作系统架构师”
扫描下方二维码👇,开启从 0 开始构建Agent Harness 的实战之旅。

