开门见山:一秒钟的工程结论
今天量子计算机还破不了 RSA-2048,但"今天被截获的加密流量,5-10 年后可能被解密"------这就是先存储、后解密(Harvest Now, Decrypt Later, HNDL)攻击;TLS 密钥交换(对称加密的密钥分发)立刻迁移到混合方案 X25519MLKEM768(Chrome、Firefox、Cloudflare 已默认开启),签名证书不必慌着换但要在 2028 年前规划 ML-DSA;对称加密 AES-256 和哈希 SHA-256/384 受影响极小,不需要换;真正紧迫的不是"换算法",而是先做 CBOM(密码学物料清单)盘点------不知道自己哪里用了 RSA/ECC 的组织,是 PQC 迁移的第一批受害者。
如果你赶时间,把上面这段话贴到方案评审文档里就够了。如果你接着往下读,这篇文章会回答几个更本质的问题:为什么 2026 年了,全球大厂还在拼命加速 PQC 迁移,尽管 Q-Day(量子破密日)看起来还在 2030 年之后?为什么 Red Sift 会说"后量子签名会 breaking TLS"?为什么"对称加密也危险"是一个被严重误解的结论?
一、先看清本质:为什么"量子计算机破密"是一个被严重简化的故事
1.1 一个常见的反直觉误区:"等量子计算机造出来再换就行"
这是最常见、也是最致命的误解。这种想法假设"量子威胁是一个瞬时事件"------Q-Day 到来,所有加密瞬间失效 。
真实情况完全不同。量子威胁是一个时间窗口问题,不是事件问题:
text
传统思维(错误):
现在加密 → 等量子计算机出现 → 换新算法 → 安全
真实威胁(正确):
现在加密 → 攻击者现在截获密文("Harvest")
→ 攻击者把密文存储 5-10 年
→ Q-Day 到来,量子计算机可用
→ 攻击者解密所有历史密文("Decrypt")
→ 你的 5-10 年前的数据全部泄露
这就是 Harvest Now, Decrypt Later(HNDL) 攻击------postquantum.com 的定义是:"HNDL 是指攻击者拦截并存储当今加密数据的做法,意图在量子计算机出现后解密它 "。
关键洞察 :HNDL 攻击不需要量子计算机 ------它只需要存储成本低到可以批量存密文 ,以及量子计算机在某天会出现 这两个前提。2026 年,存储成本已经低到攻击者可以轻易存储一个国家级 ISP 出口的所有加密流量。这意味着"数据被截获的那一刻"就已经是泄露的开始,即使 Q-Day 还在十年之外。
1.2 Mosca 不等式:判断"现在是否要慌"的数学公式
Post-Quantum 密码学之父 Michele Mosca 提出了著名的 Mosca 不等式,这是企业判断 PQC 迁移紧迫性的唯一严谨工具:
text
X + Y > Z → 你需要现在就行动
其中:
X = 你的数据需要保持机密的时间(年)
Y = 你的系统完成 PQC 迁移所需的时间(年)
Z = 量子计算机破解当前密码学所需的时间(年)
为什么这个公式是"必然成立"的?因为:
- 如果 X + Y > Z :你的数据在量子计算机可用前就必须保密,但你的迁移还没完成------所以从"现在"到"Q-Day"这一段时间里加密的数据,都会在 Q-Day 后被解密;
- 只有 X + Y ≤ Z 时,"现在开始迁移"才来得及------这个条件几乎对所有企业都不成立 。
Quantum Security Defence 的 CISO 指南给出了具体案例:
| 数据类型 | 保密期 X | 迁移期 Y | 估计 Q-Day Z | X + Y > Z? |
|---|---|---|---|---|
| 医疗记录 | 50-80 年 | 5 年 | 10-15 年 | 是,必须现在动手 |
| 政府机密 | 30+ 年 | 5-10 年 | 10-15 年 | 是,最紧迫 |
| 个人身份信息(PII) | 10-30 年 | 3-5 年 | 10-15 年 | 是 |
| 金融交易记录 | 7-25 年 | 3-5 年 | 10-15 年 | 是 |
| 电商交易数据 | 3-7 年 | 2-3 年 | 10-15 年 | 边界情况 |
| 日志、临时数据 | 1-3 年 | 1-2 年 | 10-15 年 | 暂不紧迫 |
Mosca 不等式的一个深刻含义 :"迁移紧迫性"不取决于"量子计算机什么时候出来",而取决于"你的数据要保密多久" 。一个医疗数据公司即使 Q-Day 是 2040 年,它 2026 年加密的病历在 2066 年仍需保密------这就意味着 2026 年加密的数据从诞生起就已注定泄露 。
这就是为什么 NSA、NIST、CISA、BSI(德国)、ANSSI(法国)等全球监管机构在 2025-2026 年都在强制推动 PQC 迁移 ------不是因为 Q-Day 近了,而是因为等它近了就晚了。
1.3 "对称加密也危险"------一个被误解的结论
很多人听过"量子计算也会破解 AES",这是一个部分正确但严重误导 的说法。
真相是:
- Shor 算法 对所有基于"因式分解 / 离散对数"的算法毁灭性打击------RSA、Diffie-Hellman、ECC(ECDSA/ECDH)、SM2 全部失效;
- Grover 算法 对所有对称密码和哈希 提供平方级加速 ------但只是加速,不是破解 。
Grover 算法的效果:把暴力搜索的复杂度从 O(2^n) 降到 O(√(2^n)) = O(2^(n/2))。也就是说: - AES-128 → 等效安全强度 64 位(不再安全);
- AES-256 → 等效安全强度 128 位(仍然安全);
- SHA-256 → 抗碰撞等效 128 位(仍然安全);
- SHA-384 → 抗碰撞等效 192 位(非常安全 )。
而且 Grover 算法在实际工程上难以并行化 ------虽然理论上可以,但并行 Grover 的加速比远低于经典暴力搜索的并行加速 。NIST 的官方立场是:"Grover 算法的威胁远比 Shor 算法小,AES-256 被认为是足够安全的" 。
结论 :对称加密和哈希只需要"把密钥长度加倍"这一最小改动 ------AES-128 换 AES-256、SHA-256 继续用但保守场景用 SHA-384。真正的 PQC 迁移战场,是 RSA/ECC/SM2 这些"非对称密码"。
二、NIST 三大标准:PQC 的"工业事实标准"
2.1 NIST 标准化历程简述
NIST 从 2016 年启动后量子密码标准化项目,历经 7 年评审、82 个候选算法、多轮淘汰 (包括 Rainbow、SIKE 在最后阶段被破解),于 2024 年 8 月 13 日正式发布三项标准:
| FIPS 编号 | 标准名 | 算法家族 | 用途 | 来源 |
|---|---|---|---|---|
| FIPS 203 | ML-KEM(Module-Lattice KEM) | 格密码(Lattice) | 密钥封装(替代 ECDH/RSA-OAEP) | 原名 CRYSTALS-Kyber |
| FIPS 204 | ML-DSA(Module-Lattice DSA) | 格密码(Lattice) | 数字签名(替代 ECDSA/RSA-Sig) | 原名 CRYSTALS-Dilithium |
| FIPS 205 | SLH-DSA(Stateless Hash-based DSA) | 哈希签名 | 数字签名(保守备选) | 原名 SPHINCS+ |
为什么叫 ML-KEM 而不叫 Kyber ?NIST 标准化时做了重命名,把算法从 CRYSTALS-Kyber 改为 ML-KEM ,移除了对"Kyber"这个特定实现的依赖,强调其模块格 数学基础。ML-KEM 和 Kyber 在功能上是同一算法,只有参数命名上有细微差异 。
为什么没有发布"四大标准" ?因为原计划的 Falcon (基于 NTRU 格的紧凑签名)因专利和实现复杂度问题仍未最终定稿 ,预计会以 FIPS 206 发布。当前已可部署的就是这三大标准。
2.2 ML-KEM:密钥封装机制详解
ML-KEM 是密钥封装机制(KEM),不是密钥交换 ------这个区分在工程实现上极其关键 。
KEM vs Key Exchange 的本质差异:
text
ECDH(密钥交换 Key Agreement):
- 双方各自有静态或临时密钥对
- 各自计算 shared_secret = pub_key^priv_key
- 双方必须都贡献密钥材料
ML-KEM(密钥封装 Key Encapsulation):
- 接收方有静态密钥对(pk, sk)
- 发送方调用 Encaps(pk) → (ciphertext, shared_secret)
- 发送方把 ciphertext 发给接收方
- 接收方调用 Decaps(sk, ciphertext) → shared_secret
- 只有接收方贡献密钥材料,发送方使用接收方公钥
这个差异在 TLS 里的工程含义 :TLS 1.3 用 (EC)DHE 做前向安全,双方各生成临时密钥;PQC 时代改为"接收方(服务器)有 ML-KEM 临时密钥对,发送方(客户端)封装",TLS 1.3 的握手流程改为客户端发送 encapsulated key,服务器解封装 ------这就是 IETF 正在标准化的 ML-KEM for TLS 1.3 。
ML-KEM 的三个参数集:
| 参数集 | NIST 安全级别 | 等效对称强度 | 公钥大小 | 密文大小 | 私钥大小 |
|---|---|---|---|---|---|
| ML-KEM-512 | Level 1 | AES-128 | 800 B | 768 B | 1632 B |
| ML-KEM-768 | Level 3 | AES-192 | 1184 B | 1080 B | 2400 B |
| ML-KEM-1024 | Level 5 | AES-256 | 1568 B | 1568 B | 3168 B |
为什么默认推荐 ML-KEM-768 ?qramm.org 指出:"ML-KEM-768 为大多数应用提供了强后量子安全(等效 AES-192),同时密钥和密文尺寸合理 "。Chrome、Firefox、Cloudflare 默认都用 ML-KEM-768,Level 3 是"国家级攻击者都难以破解"的标准。
2.3 ML-DSA vs SLH-DSA:签名算法的选择困境
| 维度 | ML-DSA(Dilithium) | SLH-DSA(SPHINCS+) |
|---|---|---|
| 数学基础 | Module-LWE 格问题 | 仅依赖哈希函数(最保守) |
| 签名速度 | 极快(微秒级) | 慢(毫秒级) |
| 签名大小 | 2420-4627 B | 7856-49856 B(非常大) |
| 公钥大小 | 1312-2592 B | 32-64 B(极小) |
| 实现复杂度 | 中等(需要浮点/格运算) | 简单(仅哈希) |
| 安全性保守度 | 中等(新数学假设) | 极高(40+ 年哈希信任) |
| NIST 推荐 | 默认 | 保守备选 |
ML-DSA-65 的关键尺寸:
- 公钥:1952 字节 (对比 ECDSA P-256 的 64 字节------大 30 倍);
- 私钥:4032 字节 (对比 ECDSA 的 32 字节------大 126 倍);
- 签名:3309 字节 (对比 ECDSA P-256 的 64 字节------大 52 倍 )。
Red Sift 的著名博客《Why post-quantum signatures are breaking TLS》算了一笔账 :ML-DSA 签名比 ECDSA 大 34 倍 ,一张 ML-DSA 证书链总大小能突破 14.5 KB 的 TCP 拥塞窗口 ------这意味着一次 TLS 握手需要多轮 RTT 才能传完证书,直接拖慢握手性能 。Cloudflare 的 1.1.1.1 在 2026 年 9 月支持 ML-DSA-44 的 DNSSEC 时,签名是 2420 字节 ------比传统 ECDSA 的 64 字节大 38 倍。
选择原则: - 公网 TLS、代码签名、高频签名 → ML-DSA-65(性能优先);
- 根 CA、长期不可变的签名(如代码签名根) → SLH-DSA(算法保守性优先);
- 两者都可以做"混合签名"------一张证书同时含 ECDSA + ML-DSA 签名,未来 5-10 年是主流形态。
2.4 完整 PQC 算法选型对照表
| 用途 | 现行算法 | PQC 替代 | 推荐迁移时间 |
|---|---|---|---|
| TLS 密钥交换 | X25519 / ECDH P-256 | X25519MLKEM768(混合) | 立即 |
| TLS 服务器证书 | RSA-2048 / ECDSA P-256 | ML-DSA-65(或混合) | 2027-2028 |
| 根 CA 签名 | RSA-4096 / ECDSA P-384 | SLH-DSA 或 ML-DSA-87 | 2028-2030 |
| 代码签名 | RSA-4096 / ECDSA P-384 | ML-DSA-65 或 SLH-DSA | 2027-2029 |
| JWT/Token 签名 | RS256 / ES256 | ML-DSA(待 IETF JOSE 标准化) | 2027-2028 |
| 数据加密(信封) | RSA-OAEP 包装 KEK | ML-KEM-768 封装 KEK | 立即 |
| 对称加密 | AES-128 | AES-256(升级) | 立即(最小改动) |
| 哈希 | SHA-256 | SHA-256 继续用 / SHA-384 | 不变 |
| HMAC | HMAC-SHA256 | HMAC-SHA384 | 保守升级 |
| 密码存储 | Argon2id | Argon2id(不变) | 不变 |
| TLS AEAD | AES-128-GCM / ChaCha20 | AES-256-GCM / XChaCha20 | 升级到 256 位 |
三、混合迁移:为什么"必须 hybrid",怎么实现
3.1 为什么不能直接换成 PQC?
两个不可回避的工程问题:
问题 1:PQC 算法还太年轻
RSA 已经被研究了 48 年(1977 年至今),ECC 38 年,而 ML-KEM 的底层格密码从 2005 年算起只有 21 年,大规模审查只有 10 年 。虽然目前没有实质攻击,但"新算法被破解"的概率比"老算法被破解"高一个数量级 ------SIKE 和 Rainbow 在 NIST 最后一轮被破解就是血淋淋的教训。
问题 2:部署路径不一致
不是所有客户端都支持 PQC------2026 年全球仍有大量老版本 TLS 栈、嵌入式设备、企业代理、防火墙在用纯 RSA。如果服务器只支持 ML-KEM,这些客户端直接连不上 。
解决方案:混合密钥交换 ------同时使用经典算法和 PQC 算法,只要任意一方安全,密钥就安全:
text
shared_secret = KDF( X25519_secret || ML-KEM_secret )
攻击者要破解 shared_secret,必须同时:
1. 破解 X25519(需要量子计算机)
2. 破解 ML-KEM(需要找到格密码漏洞)
任何一个被破解,混合仍然安全
3.2 X25519MLKEM768:已部署的工业标准
X25519MLKEM768 是 IETF 标准化的混合密钥交换组,组合 X25519(ECC)+ ML-KEM-768(格) ,在 TLS 1.3 中以 named group 形式协商。
部署现状(2026 年 9 月):
- Chrome 124+ 、Firefox 132+ 、Safari 18+ 、Edge 默认开启;
- Cloudflare 自 2022 年开始测试,2024 年生产默认开启,目前网络流量中 PQC 占比持续上升;
- Cloudflare 2026 年 9 月推出 Automatic Key Exchange ------探测客户源的 TLS 能力,自动选择最安全的算法(优先 PQC) ,覆盖 45 亿日连接;
- AWS、GCP、Azure 的负载均衡器在 2025-2026 年陆续开启支持;
- OpenSSL 3.5+ 已包含 ML-KEM,OpenJDK 24 通过 JEP 496/497 提供 Java 原生支持。
为什么用 ML-KEM-768 而不是 1024 ?768 已经提供 AES-192 等效强度 ,密文尺寸(1080 字节)比 1024(1568 字节)小 31%,对握手延迟影响更小。这是性能与安全的工业折中。
3.3 混合握手尺寸与性能代价
TLS 1.3 ClientHello + ServerHello 的尺寸变化:
text
纯 X25519(传统):
ClientHello KeyShare: 32 字节
ServerHello KeyShare: 32 字节
总开销:64 字节
X25519MLKEM768(PQC 混合):
ClientHello KeyShare: 32 + 1184 = 1216 字节
ServerHello KeyShare: 32 + 1080 = 1112 字节
总开销:2328 字节
增加:约 2.2 KB
性能影响(Cloudflare、Red Sift 实测数据):
- 理论 RTT 0 的场景:握手时间几乎无差异(2.2KB 在 MTU 1500 内基本一帧能传完);
- 高延迟网络:增加约 5-15ms(2.2KB 可能跨包);
- Certificate 阶段 (如果用 ML-DSA 证书):增加 10-50 KB ,可能突破 TCP 初始拥塞窗口,需要服务器在 ServerHello 之后多发一轮 ACK------这是 Red Sift 指出的真正问题 。
当前的工程共识: - 密钥交换的混合 (X25519MLKEM768)→ 性能代价小,立刻部署;
- 签名的 PQC 化 (ML-DSA 证书)→ 性能代价大,2027-2028 再说,先用 hybrid 证书(双签名)过渡。
3.4 PQC 迁移的优先级:密钥交换 > 签名
这里有一个非常重要的优先级排序,很多团队搞反了:
text
【错误排序】先换根证书(签名)→ 再换 TLS 密钥交换
【正确排序】先换 TLS 密钥交换 → 再换证书签名
为什么?
1. 密钥交换保护的是"传输中数据"(受 HNDL 攻击),
签名保护的是"身份认证"(不受 HNDL 攻击)
2. HNDL 攻击只影响"机密性",不影响"认证"
→ 现在截获的 TLS 流量,Q-Day 后能解密 → 真实威胁
3. 历史签名无法"存储后伪造"------签名验证是实时发生的,
Q-Day 攻击者也无法回头伪造"3 年前网站对用户认证的签名"
4. 唯一受 HNDL 影响的签名场景是"代码签名长期分发",
或"具有长期法律效力的签名"(如合同、公证)
这就是为什么 Chrome/Cloudflare/AWS 全部优先做 X25519MLKEM768 ------它是 HNDL 风险的最大、最现实的堵点。
四、Crypto-Agility:迁移之前必须先做 CBOM
4.1 CBOM:密码学物料清单
Cycode 把 CBOM(Cryptography Bill of Materials)定义为 :"对软件系统中每一个密码学资产的结构化清单------算法、密钥长度、证书配置...... "。CycloneDX(SBOM 标准)已扩展支持 CBOM 。
为什么 PQC 迁移的第一步是 CBOM 而不是换算法 ?因为绝大多数企业根本不知道自己哪里用了 RSA/ECC。一个典型的中型企业可能有:
- 1000+ 证书(TLS、mTLS、代码签名、内部 CA、客户端证书);
- 5000+ 数据库字段(部分用 RSA-OAEP 加密);
- 300+ API 集成(部分用 RSA 签名);
- 几十个硬编码密钥(藏在代码或配置文件里);
- 历史备份 (10 年前的备份可能还在用 3DES 或 RSA-1024)。
没有 CBOM 的 PQC 迁移就是盲人摸象。CBOM 需要记录的字段:
yaml
# 一个 CBOM 条目的样例
component:
name: "user-service"
version: "2.3.1"
type: "application"
crypto_assets:
- algorithm: "RSA-2048"
usage: "certificate-signing"
key_id: "arn:aws:kms:us-east-1:123:key/abc-123"
certificate: "CN=user-service.example.com"
expiry: "2027-06-15"
exposure: "public"
pqc_replacement: "ML-DSA-65"
migration_priority: "P1"
- algorithm: "AES-128-GCM"
usage: "data-encryption"
key_id: "internal-hsm-key-0042"
exposure: "internal"
pqc_replacement: "AES-256-GCM"
migration_priority: "P2"
CBOM 工具链:
- CycloneDX CBOM 标准;
- IBM Quantum Safe 、Keyfactor CBOM 、Venafi TLS Protect 、Entrust CipherTrust;
- SandboxAQ HQA(自动扫描代码库识别密码 API);
- 开源 :Census (SAP 开源)、cbomkit(IBM)。
4.2 CNSA 2.0 与 NIST IR 8547 时间表
NSA 的 CNSA 2.0(Commercial National Security Algorithm Suite 2.0) 给出了明确的时间表:
| 时间节点 | CNSA 2.0 要求 |
|---|---|
| 2025-2030 | 新系统开始支持 PQC,优先部署在国家安全系统 |
| 2030 | 软件/固件签名必须支持 PQC |
| 2031 | 浏览器和云服务必须支持 ML-KEM |
| 2033 | 传统 RSA/ECC 在 NSS(国家安全系统)中完全废弃 |
| 2035 | 所有 NSS 完全迁移到 CNSA 2.0 |
| NIST IR 8547(初稿) 提出对非 NSS 系统的建议时间表: |
- 2030 年后 RSA-2048、ECC P-256 不再推荐用于新部署;
- 2035 年 彻底弃用。
对国内企业的意义 :即使你的系统不在"美国国家安全系统"范围内,中国、欧盟、日本都在制定类似时间表 。中国密码管理局推动国密 PQC(基于 SM 系列的 PQC 标准在研),《密码法》和密评 3.0 预计会加入 PQC 要求 。国际化的业务必须同时准备 NIST PQC 和国密 PQC 两条路线。
4.3 PQC 迁移的五阶段路线图
text
【Phase 1:Discovery(1-3 个月)】
- 扫描代码库(Census、HQA)
- 扫描证书资产(crt.sh、内部 CA、企业 PKI)
- 扫描数据加密(数据库字段、备份)
- 构建 CBOM
- 输出:完整的密码学资产清单
【Phase 2:Risk Assessment(1 个月)】
- 按 Mosca 不等式给每个资产分级
- 高风险:长期保密数据 + RSA/ECC(医疗、金融、政府)
- 中风险:短期数据 + RSA/ECC
- 低风险:临时数据、对称加密
- 输出:迁移优先级矩阵
【Phase 3:Quick Win - Key Exchange(3-6 个月)】
- 启用 TLS 1.3 + X25519MLKEM768
- 升级 CDN、负载均衡器、反向代理
- 内部 mTLS 同步升级
- 升级 AES-128 → AES-256
- 输出:传输层 PQC 化完成
【Phase 4:Signature Migration(12-24 个月)】
- 新证书支持混合签名(ECDSA + ML-DSA)
- 根 CA 准备 PQC 版本(双轨)
- 代码签名升级
- JWT/Token 签名升级
- 输出:签名层 PQC 化完成
【Phase 5:Crypto-Agility(持续)】
- 部署 CBOM 自动化监控
- 建立"算法切换"能力(无需改代码)
- 持续跟踪 NIST/ISO/国密 PQC 更新
- 输出:可持续的密码学治理体系
五、代码实战:用 liboqs 体验 ML-KEM
5.1 liboqs 简介
liboqs 是 Open Quantum Safe(OQS)项目的核心 C 库 ,由 PQ Code Package 维护、Linux 基金会下的 Post-Quantum Cryptography Alliance 支持 。它实现了 NIST 三大标准的所有参数集,并提供统一的 C API。
liboqs 的核心特点:
- 开源(MIT License);
- 多平台(Linux/macOS/Windows,x86_64/ARM);
- 统一 API ------所有 KEM 算法共用一套接口,算法可热切换;
- 作为 OpenSSL 3 Provider 集成------可以在标准 OpenSSL 里使用 PQC。
5.2 Python 实战:ML-KEM 密钥封装
python
# pip install liboqs-python
# 前置:安装 liboqs C 库
# git clone https://github.com/open-quantum-safe/liboqs
# cd liboqs && mkdir build && cd build
# cmake -DBUILD_SHARED_LIBS=ON .. && make -j && sudo make install
from oqs import KeyEncapsulation, Signature
import os
# ============ 1. ML-KEM-768 密钥封装实战 ============
# 接收方(如服务器):生成 ML-KEM 密钥对
with KeyEncapsulation('ML-KEM-768') as recipient_kem:
public_key = recipient_kem.generate_keypair()
secret_key = recipient_kem.export_secret_key()
print(f"公钥大小: {len(public_key)} 字节") # 1184
print(f"私钥大小: {len(secret_key)} 字节") # 2400
# 发送方(如客户端):用接收方公钥封装对称密钥
# Encaps 输出: (ciphertext, shared_secret)
with KeyEncapsulation('ML-KEM-768') as sender_kem:
ciphertext, sender_shared_secret = sender_kem.encap_secret(public_key)
print(f"密文大小: {len(ciphertext)} 字节") # 1080
print(f"共享密钥大小: {len(sender_shared_secret)} 字节") # 32
# 接收方:解封装,得到相同的共享密钥
recipient_shared_secret = recipient_kem.decap_secret(ciphertext)
# 双方得到相同的 32 字节密钥,可用于 AES-256-GCM
assert sender_shared_secret == recipient_shared_secret
print("共享密钥匹配,可用于对称加密!")
# ============ 2. ML-DSA-65 签名实战 ============
with Signature('ML-DSA-65') as signer:
public_key = signer.generate_keypair()
message = b"Important message to sign"
# 签名
signature = signer.sign(message)
print(f"\n签名大小: {len(signature)} 字节") # 3309
# 对比:ECDSA P-256 签名是 64 字节(大 52 倍)
# 验证
with Signature('ML-DSA-65') as verifier:
is_valid = verifier.verify(message, signature, public_key)
print(f"签名验证: {is_valid}") # True
# ============ 3. 完整的信封加密:ML-KEM + AES-256-GCM ============
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
def pqc_envelope_encrypt(plaintext: bytes, mlkem_public_key: bytes) -> tuple:
"""用 ML-KEM-768 做 PQC 信封加密"""
with KeyEncapsulation('ML-KEM-768') as kem:
# 封装生成 AES-256 密钥
ciphertext_kem, aes_key = kem.encap_secret(mlkem_public_key)
# 用 AES-256-GCM 加密数据
nonce = os.urandom(12)
aesgcm = AESGCM(aes_key)
ciphertext = aesgcm.encrypt(nonce, plaintext, None)
# 返回 (KEM 密文, nonce, 数据密文)
# 接收方需要 KEM 密文解出 AES 密钥,再用 AES 密钥解数据
return (ciphertext_kem, nonce, ciphertext)
# 完整流程演示
with KeyEncapsulation('ML-KEM-768') as kem:
pk = kem.generate_keypair()
ct_kem, nonce, ct_data = pqc_envelope_encrypt(b"Quantum-safe data", pk)
# 接收方解密
aes_key = kem.decap_secret(ct_kem)
aesgcm = AESGCM(aes_key)
plaintext = aesgcm.decrypt(nonce, ct_data, None)
print(f"\n解密结果: {plaintext.decode()}")
5.3 OpenSSL 3.5+ 命令行实战
bash
# ============ 生成 ML-KEM-768 密钥 ============
openssl genpkey -algorithm ML-KEM-768 -out mlkem768.key
openssl pkey -in mlkem768.key -text -noout | head -20
# ============ 生成 ML-DSA-65 签名密钥 ============
openssl genpkey -algorithm ML-DSA-65 -out mldsa65.key
openssl pkey -in mldsa65.key -text -noout | head -20
# ============ 用 ML-DSA 签发 PQC 证书(自签名测试)============
# 注意:浏览器尚不支持 ML-DSA 证书,仅用于内部测试
openssl req -new -x509 -key mldsa65.key -out mldsa65.crt \
-days 365 -subj "/CN=pqc-test.example.com"
# ============ 测试 TLS 1.3 + X25519MLKEM768 ============
# 启动服务端(需要 OpenSSL 3.5+)
openssl s_server -accept 4433 -cert cert.pem -key key.pem \
-groups X25519MLKEM768 -tls1_3
# 客户端连接
openssl s_client -connect localhost:4433 \
-groups X25519MLKEM768 -tls1_3
# 观察输出中的 "Negotiated TLS1.3 group: X25519MLKEM768"
5.4 Java 原生支持(OpenJDK 24+)
OpenJDK 24 通过 JEP 496(ML-KEM) 和 JEP 497(ML-DSA) 提供 Java 原生支持:
java
// Java 24+
import java.security.*;
import javax.crypto.KeyAgreement;
// ============ ML-KEM 密钥对生成 ============
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM");
kpg.initialize(768); // ML-KEM-768
KeyPair keyPair = kpg.generateKeyPair();
// ============ KEM 封装/解封装 ============
KEM kem = KEM.getInstance("ML-KEM");
KEM.Encapsulator enc = kem.newEncapsulator(publicKey);
KEM.Encapsulated encapsulated = enc.encapsulate();
SecretKey sharedSecret = encapsulated.key();
byte[] ciphertext = encapsulated.encapsulation();
// 接收方解封装
KEM.Decapsulator dec = kem.newDecapsulator(privateKey);
SecretKey recovered = dec.decapsulate(ciphertext);
// 双方 sharedSecret 相同,可用于 AES-GCM
六、FAQ:最常见的 5 个问题
Q1:现在真的需要慌吗?量子计算机不是还很远吗?
不需要"慌",但需要"立刻开始" 。Q-Day 可能还有 8-15 年,但 Mosca 不等式告诉我们:保密期长的数据(医疗、政府、个人身份)今天加密时就已经注定泄露 。正确的心态是"按部就班地紧迫" ------不是恐慌采购,而是 2026 年启动 CBOM、2027 年完成密钥交换迁移、2030 年完成签名迁移。
Q2:PQC 算法比传统算法慢多少?
ML-KEM 比 X25519 略慢但可接受 (毫秒级内)。真正的性能挑战在签名 :ML-DSA 签名比 ECDSA 慢约 2-3 倍,但签名大小大 34-52 倍 ------这是真正的网络性能问题。Cloudflare 通过混合签名和证书优化缓解了这一问题。
Q3:国密 SM2/SM4 怎么应对 PQC?
国密的 PQC 标准正在制定中 。SM2 是 ECC,完全受 Shor 算法威胁 ;SM4/SM3 与 AES/SHA 类似,只需升密钥长度。国内金融、政务系统需要同时跟踪 NIST PQC 和国密 PQC 两条路线 ,密评 3.0 预计会引入 PQC 要求。
Q4:区块链的 ECDSA 会被破解吗?
会 。比特币、以太坊用的 ECDSA secp256k1 完全受 Shor 算法威胁 。攻击者看到一笔交易的公钥(已暴露在链上)后,Q-Day 后可以用量子计算机推导私钥 ,进而伪造签名转移资金。但攻破的是"已暴露公钥的钱包" ,未使用的钱包(公钥未公开)暂时安全。以太坊已经在规划账户抽象 + PQC 签名迁移 。
Q5:怎么检测我的系统是否 PQC 就绪?
工具化检查:
- CBOM 扫描:Census、IBM HQA、Keyfactor CBOM;
- TLS 测试 :testssl.sh 加
-groups参数检查是否支持 X25519MLKEM768; - 证书审计:crt.sh 检查所有证书的签名算法;
- 代码扫描:grep 所有 RSA、ECDSA、ECDH 关键词;
- 对照清单:用本文七层清单逐项自查。
七、结语:密码学工程是一场与时间的赛跑
写到这里,你可能已经看到本文反复出现的主题------
PQC 迁移的本质,不是"应对一个还不存在的威胁",而是"承认密码学算法终将被淘汰"这一事实 。从 RSA-1024 到 RSA-2048,从 SHA-1 到 SHA-256,从 SSL 到 TLS 1.3------密码学工程史就是一部"提前迁移"的历史 。量子计算只是把"算法被淘汰"的触发器从"数学攻击被发明"变成了"硬件计算能力到达阈值"。
为什么 2026 年就要开始 PQC 迁移? 因为:
- HNDL 攻击今天就在发生------你今天加密的数据可能已经被存储;
- 迁移需要 3-10 年------大型企业的密码学资产盘点和替换从来不是一蹴而就;
- 算法需要时间"成熟"------ML-KEM 还需要 5-10 年的真实世界考验才能像 RSA 一样被信任;
- 合规在逼近------CNSA 2.0、NIST IR 8547、密评 3.0 的时间表都已明确。
密码学工程的第一铁律 :不要相信"量子计算机还很远所以不用慌" 。是否紧迫不取决于 Q-Day 什么时候来,而取决于你的数据要保密多久 + 你的迁移需要多久 。当 X + Y > Z 时,今天就是最后期限 。
PQC 迁移的真正难点,不是数学,是组织 ------是让 100 个团队在 3 年内协调替换 1000 张证书、5000 个加密字段、300 个 API,这才是真正考验一个组织 Crypto-Agility 的地方。