你以为 HTTPS 够安全就够了?今天 Chrome 154 把这件事用 WebCrypto 原生化了
很长时间里,前端工程师谈「浏览器做加密」,聊的都是 HTTPS TLS 握手那一层——底层是浏览器和服务器之间的事,跟应用层代码没什么关系。应用层要做签名、要验固件、要给 JWT 盖时间戳,对不起,你得接一个第三方 crypto 库。
这件事今天被 Chrome 154 彻底翻了。
发生了什么
Chrome 154 稳定版正式把后量子加密算法写进了 WebCrypto API。准确说,是三件事同时落地:ML-KEM(后量子密钥封装)、ML-DSA(后量子数字签名)、ChaCha20-Poly1305(认证加密)。这三个都是 NIST 在 2024 年正式发布的标准(分别对应 FIPS 203/204),不是草稿,不是实验性质,是生产可用的标准算法。
ML-KEM 用来做密钥交换。TLS 层面 Chrome 从 124 版本就开始用混合模式(X25519 + ML-KEM)默认跑后量子密钥交换了,但那是传输层的事,跟你的 JavaScript 没关系。现在你在浏览器里可以直接生成 ML-KEM 密钥对、做 encapsulation(生成密文)和 decapsulation(恢复共享密钥),全程原生 API,不需要任何第三方库。
ML-DSA 用来做数字签名。对应的是 RSA/ECDSA 在签名场景的替代品。三个参数集分别对应三个 NIST 安全级别:ML-DSA-44(128 位)、ML-DSA-65(192 位)、ML-DSA-87(256 位)。固件签名用 65,应用层签名用 44。
ChaCha20-Poly1305 是对称认证加密,替代 AES-GCM 的选项,尤其适合移动端。
以前是什么样子
TLS 层面,Chrome 124 就默认启用了 X25519MLKEM768 混合密钥交换,你访问的所有 HTTPS 网站从那时候起就已经在用后量子密钥封装保护传输层了。这件事是悄悄发生的,你什么都没改,但你的流量已经在抵抗「现在收集,以后量子计算机解密」的 harvest-now-decrypt-later 攻击。
但应用层完全是另一回事。你要在浏览器里给一个固件镜像做签名?以前只有三条路:接 WebAssembly 编译的 libsodium、接后端的签名服务、或者干脆不管。
这个空白今天被填上了。
三行代码用起来
ML-KEM 密钥生成和 encapsulation:
“`javascript
// 生成接收方密钥对
const { publicKey, privateKey } = await crypto.subtle.generateKey(
‘ML-KEM-768’, // 三个参数集:ML-KEM-512 / ML-KEM-768 / ML-KEM-1024
true, // extractable
[‘encapsulate’, ‘decapsulate’]
);
// 发送方:用公钥生成共享密钥和密文
const { ciphertext, sharedKey } = await crypto.subtle.encapsulate(publicKey);
// ciphertext = 1088 bytes,sharedKey = 32 bytes
“`
ML-DSA 签名:
“`javascript
// 生成签名密钥对
const { publicKey, privateKey } = await crypto.subtle.generateKey(
‘ML-DSA-65’, // 三选一:44 / 65 / 87
true,
[‘sign’, ‘verify’]
);
// 签名
const signature = await crypto.subtle.sign(
null, // 参数集自带哈希算法,无需单独指定
privateKey,
new Uint8Array(message)
);
// signature size ≈ 3309 bytes(ML-DSA-65)
“`
功能检测(渐进增强):
“`javascript
const algorithms = await crypto.subtle.supports();
if (algorithms.includes(‘ML-KEM-768’)) {
// 可以用后量子 KEM 做密钥交换
}
if (algorithms.includes(‘ML-DSA-65’)) {
// 可以做后量子签名
}
“`
三个坑
第一个坑是签名体积。ML-DSA-65 的签名是 3309 字节,而 Ed25519 签名是 64 字节,差了 50 倍。你的 JWT 如果每个都带签名,体积会爆炸。证书链里的签名也会更粗,这是从一开始就要做容量规划的,不是迁移完再优化。
第二个坑是 ChaCha20-Poly1305 在桌面端反而可能更慢。ChaCha20 的优势在移动端 Arm 架构,x86/x64 桌面用 AES-NI 硬件加速反而更快。
第三个坑是目前只有 Chrome 154。Firefox 135+ 支持 ML-KEM 的 TLS 层但 WebCrypto 应用层还在接;Safari 18+ 有 ML-KEM 支持;其他浏览器暂时空白。功能检测必须做。
三步下一步
第一步,审计你现在的 crypto 依赖。如果你的应用还在用 window.atob/Node buffer 做 base64 编码做签名,或者接了一个 30KB 的 WASM crypto 库,先换成 WebCrypto 的原生 API,顺便把后量子支持加上,迁移成本为零。
第二步,先从长期敏感数据开始。固件签名用 ML-DSA-65,应用层签名用 ML-DSA-44,短期 JWT 用 ECDSA P-256 继续跑着。
第三步,把 hybrid 思路带进来。Chrome 现在跑的是 X25519MLKEM768——古典算法和后量子算法并联,任一被破另一个还管用。你的应用层也可以:主流流量用 ECDSA P-256,敏感流量用 ML-DSA,两条腿走路。
浏览器从传输层到应用层第一次具备了完整的生产级后量子加密能力。接下去的问题是:你什么时候开始用它?
评论区
登录后可评论。