ML-DSA 与 ECDSA 的取舍,是后量子过渡中签名的那一半。基于 P-256 的 ECDSA 签名只有 64 字节,而且无处不在,但 Shor 算法能攻破它。ML-DSA(FIPS 204,2024年8月)能抵御已知的量子攻击,速度也快,但它的密钥和签名都以千字节计。密钥交换方面,混合 ML-KEM 已经是浏览器的默认选择;签名迁移则不同,大部分工作仍在前面。
概览
| ECDSA P-256 | ML-DSA-44 | ML-DSA-65 | ML-DSA-87 | |
|---|---|---|---|---|
| 安全性 | 经典安全性约 128 位,可被 Shor 算法攻破 | 类别 2 | 类别 3 | 类别 5 |
| 公钥 | 65 字节(SPKI DER 为 91) | 1,312(SPKI DER 为 1,334) | 1,952(1,974) | 2,592 |
| 签名 | 原始格式 64 字节,DER 为 70~72 | 2,420 字节 | 3,309 字节 | 4,627 字节 |
| 自签名证书(实测) | 约 388 字节 | 约 3,985 字节 | 约 5,514 字节 | 未测量 |
| 每秒签名次数(OpenSSL 3.6.5) | 约 87,000 | 约 3,900 | 约 2,400 | 约 2,050 |
| 每秒验证次数 | 约 29,000 | 约 20,800 | 约 13,600 | 约 8,500 |
| 标准 | FIPS 186-5(2023年) | FIPS 204(2024年) | FIPS 204 | FIPS 204 |
| X.509 标识符 | ecdsa-with-SHA256 | RFC 9881 OID …3.4.3.17 至 .19 | ||
| NIST IR 8547(草案) | 2035年后禁止使用 | 批准使用 | 批准使用 | 批准使用(CNSA 2.0 的选择) |
速度用 openssl speed 在 Apple M4 Max 的单个核心上测得。OpenSSL 的 ML-DSA 是可移植的 C 代码;经过优化的实现签名速度要快好几倍。
为什么需要更换
ECDSA 依赖椭圆曲线离散对数问题,而在大型容错量子计算机上,Shor 算法可以高效地解决这个问题。这样的机器目前还不存在,对它何时可能出现的估计也相差很大,但签名有一个决定其紧迫程度的特性:日后伪造签名,并不能撤销过去已经完成的身份验证。2026年用 ECDSA 完成身份验证的 TLS 握手,无法像被记录下来的密钥交换那样遭到事后攻击。真正需要尽早关注的,是签名必须在很多年内保持可信的一切:根 CA 和中间 CA 的密钥、固件和启动链、代码签名根、法律文书和长期归档。
ML-DSA 是一种基于格的签名方案(源自 CRYSTALS-Dilithium),安全性建立在 Module-LWE 和 Module-SIS 之上,除通用方法外,没有已知的量子加速手段。NIST IR 8547(初始公开草案)提议在2035年后禁止使用 ECDSA、EdDSA 和 RSA;NSA 的 CNSA 2.0 要求国家安全系统使用 ML-DSA-87,其中软件和固件签名率先迁移。
大小问题
迁移之所以困难,在于大小。TLS 服务器用证书链和一个握手签名完成身份验证;使用 ECDSA 时,叶子证书和中间证书的公钥、它们的签名、两个内嵌的 SCT 以及 CertificateVerify 签名加起来只有几百字节。换成 ML-DSA-44,同样这些元素约为 14.7 KB(两个 1,312 字节的公钥加上五个 2,420 字节的签名:两个在证书上,两个在 SCT 中,还有一个是 CertificateVerify),用 ML-DSA-65 则更大。这会让服务器的第一轮握手消息超出 TCP 初始拥塞窗口,增加往返次数,还会让 QUIC 的放大限制更加吃紧。
#!/bin/sh
dir=$(mktemp -d)
cd "$dir" || exit 1
for alg in EC ML-DSA-44 ML-DSA-65; do
if [ "$alg" = EC ]; then
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out key.pem 2>/dev/null
label="ECDSA P-256"
else
openssl genpkey -algorithm "$alg" -out key.pem 2>/dev/null
label="$alg"
fi
openssl req -new -x509 -key key.pem -subj "/CN=example.com" -days 90 -outform DER -out cert.der 2>/dev/null
printf '%-12s certificate %5s bytes\n' "$label" "$(wc -c < cert.der | tr -d ' ')"
done
cd / && rm -rf "$dir"
ECDSA P-256 certificate 388 bytes
ML-DSA-44 certificate 3985 bytes
ML-DSA-65 certificate 5514 bytes
Web PKI 的应对方案仍在设计之中。Chrome 于2026年2月宣布,计划依靠 Merkle 树证书(IETF PLANTS 互联网草案,用简短的包含证明取代大部分逐张证书的签名),并且不打算把后量子 X.509 证书加入其现有的根证书库。CA/Browser Forum 尚未批准将 ML-DSA 用于公开受信任的 TLS 证书。私有 PKI 已经可以依据 RFC 9881 签发 ML-DSA 证书,OpenSSL 3.5 及更高版本、Bouncy Castle 等库也都支持这类证书。
混合与复合方案
在过渡期间,许多部署希望签名对新旧客户端都能通过验证,或者在其中任一算法失效时仍然安全:
- 复合签名(draft-ietf-lamps-pq-composite-sigs,仍是互联网草案)定义单一的算法标识符,例如 ML-DSA-65 搭配 ECDSA P-256,只有两部分都验证通过,签名才有效。OpenPGP 的 RFC 9980 以 ML-DSA-65+Ed25519 采取了同样的做法,OpenSSH 10.4 也增加了实验性的 ML-DSA-44+Ed25519 密钥类型。
- 双重签名附加两个相互独立的签名(CMS 支持多个
SignerInfo结构;一些文档格式允许多个签名字段),每个验证方各自检查自己能理解的那一个。 - 并行 PKI 同时签发经典证书和后量子证书,由客户端选择;TLS 协商已经通过
signature_algorithms支持这种模式。
如何选择
- 公共 TLS 服务器证书、通行密钥、OIDC 和公开的 JWT:目前用 ECDSA(或 Ed25519);关注浏览器和 IETF 的相关工作,以便适时切换。
- 为长期运行的服务和设备搭建的私有 PKI:ML-DSA-65;如果两类验证方并存,则使用 ML-DSA 加 ECDSA 的复合签名。
- 固件和安全启动:ML-DSA-87,或者基于哈希的 LMS、XMSS 或 SLH-DSA,取决于你是否需要符合 CNSA 2.0。
- 代码和软件包签名:随着各个生态(Sigstore、操作系统厂商)陆续提供支持,在现有签名之外添加 ML-DSA 签名。
- 区块链:选择权不在你手里;已有针对多条链的后量子签名提案,但在比特币或以太坊上都还没有广泛部署。
- 短期令牌和会话:在验证方迁移之前,继续使用 ECDSA 没有问题,因为伪造只在令牌和会话仍然有效时才构成风险。
迁移说明
- 盘点每一个签名密钥和验证方(密码物料清单会有帮助),记录密钥有效期以及由谁验证。
- 去掉对大小的假设:数据库列、HTTP 头部大小限制(ML-DSA-65 签名经 base64 编码后约为 4.4 KB)、智能卡存储、QR 码和 DNS 记录。
- 让算法可协商:在格式中携带算法标识符,在验证方中设置允许列表,并使用密钥标识符,以便新密钥能与旧密钥并存。
- 从长期有效的根开始:现在就为私有 PKI 创建 ML-DSA 或复合签名的根证书和中间证书,因为根证书需要数年才能分发到位。
- 在真实路径上测试性能:更大证书链下的握手延迟、签名吞吐量(在可移植代码中比 ECDSA 慢一个数量级)、受限设备上的验证。
- 持续关注 FIPS 和策略状态:FIPS 204 已定稿,NIST IR 8547 仍是草案,复合签名也仍是草案,WebPKI 规则尚未改变。