RSA-2048 在经典计算机上需要 300 万亿年才能破解,在量子计算机上只需要几小时。Shor 算法把大数分解从指数时间降到多项式时间——RSA 和 ECC 的安全基础直接崩塌。更紧迫的是”先收集,后解密”攻击:攻击者现在截获你的 TLS 流量,等量子计算机成熟后再解密。如果你保护的数据需要保密 10 年以上,这个威胁已经迫在眉睫。NIST 在 2024 年正式标准化了后量子密码算法——迁移不是未来的事,是现在的事。
一、量子计算威胁
1.1 Shor 算法:非对称加密的终结者
1994 年,Peter Shor 提出了一个量子算法,可以在多项式时间内分解大整数和计算离散对数。这意味着 RSA 和 ECC 的安全基础——大数分解困难和椭圆曲线离散对数困难——在量子计算机面前不再成立:
| 算法 | 经典计算 | 量子计算(Shor) | 影响 |
|---|---|---|---|
| RSA | 2^n(指数级) | n³(多项式级) | RSA 被破解 |
| ECC | 2^n | n³ | ECC 被破解 |
| DH | 2^n | n³ | DH 被破解 |
| AES | 2^n | 2^(n/2)(Grover) | 密钥长度需翻倍 |
Shor 算法的核心思想是用量子傅里叶变换(QFT)找到函数的周期,然后用经典算法从周期推导出因子。具体来说,要分解 N = p × q:
- 随机选 a < N,计算 gcd(a, N)
- 用量子傅里叶变换找 f(x) = a^x mod N 的周期 r
- 如果 r 是偶数,则 gcd(a^(r/2) - 1, N) 可能是 p 或 q
经典计算机执行步骤 2 需要指数时间,量子计算机只需要 O(n³)。
1.2 Grover 算法:对称加密的削弱者
Grover 算法可以将无序搜索问题从 O(N) 加速到 O(√N)。对于密码学,这意味着暴力搜索密钥的空间减半:
AES-128:经典暴力搜索 2^128 次 → Grover 搜索 2^64 次AES-256:经典暴力搜索 2^256 次 → Grover 搜索 2^128 次
结论:AES-256 在量子时代仍然安全(2^128 次搜索不可行) AES-128 需要升级到 AES-256对称加密的量子威胁远小于非对称加密——只需要将密钥长度翻倍即可。真正的危机在于 RSA 和 ECC,它们需要被全新的算法替代。
1.3 “先收集,后解密”威胁
| 威胁 | 说明 |
|---|---|
| 先收集后解密 | 攻击者现在截获加密数据,等量子计算机成熟后解密 |
| 影响范围 | 长期机密数据(国家安全、医疗记录、商业机密) |
| 时间窗口 | 量子计算机可能在 10-15 年内成熟 |
| 已知案例 | 2023 年多个 APT 组织被观察到大量收集加密流量 |
后量子迁移不是”量子计算机出现后再做”——由于”先收集后解密”威胁,现在截获的数据在未来可能被解密。对于需要长期保密的数据,必须现在就开始使用后量子密码。
1.4 量子计算机发展现状
| 指标 | 当前状态 | 破解 RSA-2048 需要 | 预计时间 |
|---|---|---|---|
| 逻辑量子比特 | ~1000 | ~4000 | 5-10 年 |
| 容错量子比特 | ~100 | ~2000 万(含纠错) | 15-20 年 |
| 纠错码 | 实验阶段 | Surface Code | 10-15 年 |
| 量子体积 | IBM 1000+ | 远超当前 | 不确定 |
破解 RSA-2048 大约需要 4000 个逻辑量子比特,但考虑纠错开销后需要约 2000 万个物理量子比特。IBM 预计 2029 年达到 10 万量子比特,但距离 2000 万仍有数量级差距。不过,技术突破可能加速这一进程。
二、格密码学基础
2.1 什么是格(Lattice)
# 格的简单示例:二维格# 格 = 基向量的所有整数线性组合import numpy as np
# 两个基向量b1 = np.array([2, 1]) # 基向量 1b2 = np.array([1, 3]) # 基向量 2
# 生成格点lattice_points = []for i in range(-3, 4): for j in range(-3, 4): point = i * b1 + j * b2 lattice_points.append(point)
# 格上的困难问题:给定目标点,找最近的格点# 这就是 CVP (Closest Vector Problem) ——Kyber 的安全基础target = np.array([3.7, 2.3])# 暴力搜索在低维可行,但在 1000+ 维不可行# 使用 liboqs 的 Kyber 密钥封装# 安装pip install liboqs-python
# 运行 Kyber768 密钥封装python3 -c "import oqswith oqs.KeyEncapsulation('Kyber768') as kem: pk = kem.generate_keypair() ct, ss_enc = kem.encap_secret(pk) ss_dec = kem.decap_secret(ct) assert ss_enc == ss_dec print(f'Shared secret: {ss_enc.hex()[:32]}...') print(f'Ciphertext size: {len(ct)} bytes') print(f'Public key size: {len(pk)} bytes')"格是 n 维空间中规则排列的点的集合。直观理解:在二维平面上,给定两个不共线的向量 v₁ 和 v₂,所有形如 a·v₁ + b·v₂(a, b 为整数)的点构成一个格。
二维格示例: · · · · · · · · · · · · · · · ·
每个点都是基向量的整数线性组合2.2 格上的困难问题
格密码的安全性基于以下问题的计算困难性:
| 问题 | 描述 | 用于 |
|---|---|---|
| 最短向量问题(SVP) | 在格中找到最短的非零向量 | 安全性基础 |
| 最近向量问题(CVP) | 给定一个点,找到格中最近的向量 | 安全性基础 |
| 带误差学习(LWE) | 从带噪声的线性方程组中恢复密钥 | Kyber/Dilithium 的直接基础 |
| 模 LWE(Module-LWE) | LWE 在环上的推广 | Kyber/Dilithium 实际使用 |
2.3 LWE 问题直觉
LWE(Learning With Errors)是格密码的核心假设。想象一个线性方程组,但每个方程的右边都加了一个小的随机误差:
标准线性方程组(无误差): 带误差的线性方程组(LWE):4x + 3y = 17 4x + 3y ≈ 17 + e₁2x + 5y = 19 2x + 5y ≈ 19 + e₂7x + 1y = 23 7x + 1y ≈ 23 + e₃
解法:高斯消元法 解法:?没有已知的高效经典算法 量子计算机也无法有效解决没有误差时,高斯消元法可以轻松求解。加入小误差后,方程组变得”模糊”——没有已知的高效算法(经典或量子)能从带误差的方程组中恢复原始密钥。
三、NIST PQC 标准
3.1 标准化历程
3.2 三个标准
| 标准 | 算法 | 用途 | 数学基础 | 替代 |
|---|---|---|---|---|
| FIPS 203 | ML-KEM (Kyber) | 密钥封装 | Module-LWE | ECDH |
| FIPS 204 | ML-DSA (Dilithium) | 数字签名 | Module-LWE + Module-SIS | RSA/ECDSA |
| FIPS 205 | SLH-DSA (SPHINCS+) | 数字签名 | 哈希函数 | 备用签名 |
3.3 ML-KEM(Kyber)详解
Kyber 是基于 Module-LWE 的密钥封装机制(KEM),用于替代 TLS 中的 ECDH 密钥交换:
# 使用 liboqs-python 测试 Kyberfrom oqs import KeyEncapsulation
# 密钥生成kem = KeyEncapsulation("Kyber768")public_key = kem.generate_keypair()
# 封装(替代 ECDH 密钥交换)ciphertext, shared_secret_enc = kem.encap_secret(public_key)
# 解封装shared_secret_dec = kem.decap_secret(ciphertext)
assert shared_secret_enc == shared_secret_dec| 参数集 | 安全等级 | 公钥大小 | 密文大小 | 共享密钥 | 对应传统方案 |
|---|---|---|---|---|---|
| Kyber512 | NIST Level 1 | 800B | 768B | 32B | AES-128 |
| Kyber768 | NIST Level 3 | 1184B | 1088B | 32B | AES-192 |
| Kyber1024 | NIST Level 5 | 1568B | 1568B | 32B | AES-256 |
与 ECDH(P-256 公钥 64B)相比,Kyber 的公钥和密文都大得多。这是后量子密码的普遍代价——更大的密钥和密文。
3.3.1 Kyber 算法概要
Kyber 的内部构造基于 Module-LWE,核心步骤如下:
密钥生成:1. 生成随机矩阵 A(n×n,每个元素是模 q 的多项式)2. 生成秘密向量 s 和误差向量 e(小系数多项式)3. 计算 t = A·s + e(模 q)4. 公钥 = (A, t),私钥 = s
封装(Encapsulate):1. 生成随机消息 m2. 计算哈希 H(m) 作为共享密钥的种子3. 生成小向量 r, e₁, e₂4. 计算 u = Aᵀ·r + e₁, v = tᵀ·r + e₂ + Encode(m)5. 密文 = (u, v)
解封装(Decapsulate):1. 计算 m' = Decode(v - sᵀ·u) // 误差在 Decode 中被消除2. 重新封装验证,防止解密失败攻击3. 共享密钥 = KDF(m' || H(ciphertext))Kyber 的核心运算是多项式环上的矩阵-向量乘法,使用数论变换(NTT)加速——类似于 FFT 在有限域上的变体。Compress/Uncompress 步骤将多项式系数从模 q 量化到更小的模,这是 LWE 误差的来源,也是安全性的根基。
3.4 ML-DSA(Dilithium)详解
Dilithium 是基于 Module-LWE + Module-SIS 的数字签名方案:
# 使用 liboqs-python 测试 Dilithiumfrom oqs import Signature
# 密钥生成signer = Signature("Dilithium3")public_key = signer.generate_keypair()
# 签名message = b"Hello, post-quantum world!"signature = signer.sign(message)
# 验证verifier = Signature("Dilithium3")is_valid = verifier.verify(message, signature, public_key)assert is_valid| 参数集 | 安全等级 | 公钥大小 | 签名大小 | 对应传统方案 |
|---|---|---|---|---|
| Dilithium2 | Level 2 | 1312B | 2420B | RSA-2048 |
| Dilithium3 | Level 3 | 1952B | 3293B | ECDSA-P-256 |
| Dilithium5 | Level 5 | 2592B | 4595B | ECDSA-P-384 |
与 ECDSA-P-256(公钥 64B,签名 64B)相比,Dilithium 的公钥和签名都大了约 20-50 倍。
3.5 SLH-DSA(SPHINCS+)详解
SPHINCS+ 是基于哈希的签名方案,安全性只依赖哈希函数的抗碰撞性——不依赖格假设:
| 维度 | Dilithium | SPHINCS+ |
|---|---|---|
| 数学基础 | 格密码 | 哈希函数 |
| 签名大小 | ~3KB | ~8-30KB |
| 安全假设 | Module-LWE + Module-SIS | 仅哈希抗碰撞 |
| 速度 | 快 | 中 |
| 推荐 | 主要签名方案 | 备用签名方案 |
SPHINCS+ 的价值在于”保守安全”——如果未来发现格问题比预期容易,SPHINCS+ 仍然安全(只要哈希函数安全)。建议将 Dilithium 作为主要签名方案,SPHINCS+ 作为代码签名等高安全场景的备用。
3.6 密钥大小对比
| 算法 | 公钥大小 | 签名/密文大小 | 用途 |
|---|---|---|---|
| RSA-2048 | 256B | 256B(签名) | 传统 |
| ECDSA-P-256 | 64B | 64B(签名) | 传统 |
| Ed25519 | 32B | 64B(签名) | 传统 |
| Kyber768 | 1184B | 1088B(密文) | PQC 密钥交换 |
| Dilithium3 | 1952B | 3293B(签名) | PQC 签名 |
| SPHINCS+-128s | 32B | 7856B(签名) | PQC 备用签名 |
后量子密码的密钥和签名普遍比传统方案大 10-50 倍,这是量子安全需要付出的带宽和存储代价。
四、混合方案与迁移
4.1 为什么需要混合方案?
在过渡期,同时使用传统算法和后量子算法是唯一安全的选择:
# 混合密钥交换:ECDH + Kyberfrom cryptography.hazmat.primitives.asymmetric import ecfrom oqs import KeyEncapsulationimport hashlib
# 1. 传统 ECDH 密钥交换ecdh_private = ec.generate_private_key(ec.SECP256R1())ecdh_shared = ecdh_private.exchange(ec.ECDH(), peer_ecdh_public)
# 2. 后量子 Kyber 密钥封装kem = KeyEncapsulation("Kyber768")kyber_ciphertext, kyber_shared = kem.encap_secret(peer_kyber_pk)
# 3. 混合共享密钥 = KDF(ECDH共享 || Kyber共享)hybrid_shared = hashlib.sha256(ecdh_shared + kyber_shared).digest()| 方案 | 经典安全 | 量子安全 | 说明 |
|---|---|---|---|
| 纯传统 | 当前默认 | ||
| 纯后量子 | (新算法可能有问题) | 未来目标 | |
| 混合 | 过渡期推荐 |
混合方案的安全性是”与”关系——攻击者必须同时破解传统算法和后量子算法才能获得共享密钥。
4.2 TLS 1.3 中的 PQC 混合密钥交换
Chrome 和 Firefox 已经开始支持 TLS 1.3 的 PQC 混合密钥交换:
TLS 1.3 PQC 混合密码套件:X25519Kyber768Draft00 — Chrome 116+ 默认启用X25519MLKEM768 — FIPS 203 发布后的标准名称
握手流程:1. ClientHello 包含 X25519 + Kyber768 的公钥2. ServerHello 返回 X25519 + Kyber768 的公钥3. 两个密钥交换的共享密钥通过 KDF 混合4. 即使 Kyber 被破解,X25519 仍然保护连接5. 即使 X25519 被量子破解,Kyber 仍然保护连接4.3 密码学敏捷性(Crypto-Agility)
密码学敏捷性是后量子迁移的基础能力——系统必须能够快速替换密码算法:
| 敏捷性维度 | 说明 | 实现方式 |
|---|---|---|
| 算法可替换 | 不硬编码算法名称 | 配置驱动,支持算法列表 |
| 密钥格式可扩展 | 支持更大的密钥 | 通用密钥存储接口 |
| 协议可协商 | 运行时协商算法 | TLS 密码套件协商 |
| 降级可控制 | 防止降级攻击 | 最低安全级别策略 |
// Go: 密码学敏捷性设计示例type CryptoSuite struct { KEM string // "X25519", "Kyber768", "X25519Kyber768" Sign string // "ECDSA-P256", "Dilithium3", "ECDSA-Dilithium" Symmetric string // "AES-256-GCM" MinLevel int // 最低安全等级(1-5)}
var SupportedSuites = []CryptoSuite{ {KEM: "X25519Kyber768", Sign: "ECDSA-Dilithium3", Symmetric: "AES-256-GCM", MinLevel: 3}, {KEM: "Kyber768", Sign: "Dilithium3", Symmetric: "AES-256-GCM", MinLevel: 3}, {KEM: "X25519", Sign: "ECDSA-P256", Symmetric: "AES-256-GCM", MinLevel: 1},}4.4 迁移路径
| 阶段 | 时间 | 行动 | 风险 |
|---|---|---|---|
| 评估 | 现在 | 盘点所有使用 RSA/ECC 的系统 | 低 |
| 测试 | 2024-2025 | 在测试环境部署 PQC | 低 |
| 混合部署 | 2025-2027 | 生产环境启用混合模式 | 中(性能/兼容性) |
| 纯 PQC | 2028+ | 根据成熟度逐步移除传统算法 | 高(新算法未经长期检验) |
后量子迁移的关键是”现在开始准备”——1)盘点密码学资产;2)建立密码学敏捷性;3)测试 PQC 实现;4)规划混合部署。不要等到量子计算机出现才开始。
五、性能影响与优化
5.1 PQC 性能对比
| 操作 | ECDSA-P-256 | Dilithium3 | 倍数 |
|---|---|---|---|
| 密钥生成 | ~0.1ms | ~0.2ms | 2x |
| 签名 | ~0.5ms | ~0.3ms | 0.6x |
| 验证 | ~1ms | ~0.1ms | 0.1x |
| 公钥大小 | 64B | 1952B | 30x |
| 签名大小 | 64B | 3293B | 51x |
| 操作 | X25519 | Kyber768 | 倍数 |
|---|---|---|---|
| 密钥生成 | ~0.05ms | ~0.1ms | 2x |
| 封装/交换 | ~0.1ms | ~0.15ms | 1.5x |
| 解封装 | ~0.1ms | ~0.15ms | 1.5x |
| 公钥大小 | 32B | 1184B | 37x |
| 密文大小 | 32B | 1088B | 34x |
PQC 的计算开销并不大(通常 2-10 倍),但密钥和密文大小显著增加,这会影响网络传输和存储。
5.2 优化策略
| 策略 | 说明 | 效果 |
|---|---|---|
| 混合模式 | 仅在需要时启用 PQC | 减少不必要的开销 |
| 证书压缩 | 压缩更大的 PQC 证书 | 减少传输量 |
| 缓存密钥 | 缓存 Kyber 密钥对 | 减少密钥生成开销 |
| 硬件加速 | 未来的 PQC 加速指令 | 类似 AES-NI 的加速 |
六、PQC 对协议的影响
6.1 TLS 握手大小
PQC 密钥比传统密钥大得多,直接影响 TLS 握手的网络开销:
| 算法组合 | ClientHello 增量 | 总握手大小 | 影响 |
|---|---|---|---|
| ECDH (传统) | 0 | ~300 字节 | 基准 |
| ECDH + Kyber768 | +1,216 字节 | ~1,500 字节 | 可能触发 MTU 分片 |
| ECDH + Kyber1024 | +1,568 字节 | ~1,900 字节 | 几乎必然分片 |
SIKE(超奇异同源密钥交换)曾是 NIST PQC 第四轮候选算法,但在 2022 年被经典计算机在 1 小时内破解。这个教训说明:密码学算法的安全性需要经过充分的同行评审,新算法在标准化之前不应投入生产使用。
6.2 代码签名与 X.509 证书
PQC 签名密钥的巨大尺寸对 PKI 体系冲击显著:
| 签名算法 | 公钥大小 | 签名大小 | 证书链总大小 |
|---|---|---|---|
| ECDSA P-256 | 64 字节 | 64 字节 | ~1 KB |
| Dilithium3 | 1,952 字节 | 3,293 字节 | ~15 KB |
| SPHINCS+-256f | 64 字节 | 29,792 字节 | ~90 KB |
证书链从 1KB 膨胀到 15-90KB,对 TLS 握手、OCSP 响应、证书存储都有显著影响。
6.3 混合 X.509 证书(RFC 9180)
混合证书在同一个 X.509 证书中同时包含传统算法和 PQC 算法的公钥和签名:
6.4 OpenSSL PQC 实践
# 使用 oqs-provider 编译的 OpenSSL 配置混合 TLS# 1. 安装 liboqs 和 oqs-providergit clone https://github.com/open-quantum-safe/liboqs.gitcd liboqs && mkdir build && cd buildcmake -DCMAKE_INSTALL_PREFIX=/usr/local .. && make -j$(nproc) && sudo make install
# 2. 生成混合密钥对(Kyber768 + X25519)openssl req -x509 -new -nodes \ -newkey "kyber768:x25519" \ -keyout hybrid-key.pem -out hybrid-cert.pem \ -days 365 -subj "/CN=hybrid-test"
# 3. 启动混合 TLS 服务器openssl s_server -cert hybrid-cert.pem -key hybrid-key.pem \ -accept 4433 -www -groups "kyber768:x25519"后量子算法的密钥和签名尺寸远大于传统算法:Kyber768 公钥 1184 字节(对比 X25519 的 32 字节),Dilithium3 签名 3293 字节(对比 Ed25519 的 64 字节)。TLS 握手消息变大可能触发 TCP 分片,增加握手延迟。
# 使用 liboqs + OpenSSL 3.x 生成 PQC 密钥对openssl req -new -newkey kyber768 -keyout kyber.key -out kyber.csr
# 生成混合证书(ECDH + Kyber)openssl req -new -newkey ec:p-256 -keyout hybrid.key \ -addkey kyber768 -out hybrid.csr
# 查看混合证书openssl x509 -in hybrid.crt -text -noout6.5 侧信道抵抗
格密码方案(Kyber/Dilithium)的实现需要抵抗侧信道攻击:
| 攻击类型 | 防御方法 | 说明 |
|---|---|---|
| 时序攻击 | 常数时间实现 | NTT 变换必须与密钥无关 |
| 功耗分析 | 掩码(Masking) | 将密钥拆分为多个随机份额 |
| 故障注入 | 冗余计算 | 重复关键运算并比较结果 |
Kyber 的 NTT(数论变换)是侧信道攻击的主要目标——如果 NTT 的执行时间依赖于密钥系数,攻击者可以通过计时推断密钥信息。生产级实现必须使用常数时间 NTT。
七、总结
上一章剖析了同态加密与隐私计算。
| 维度 | 关键要点 |
|---|---|
| 量子威胁 | Shor 破解 RSA/ECC(多项式时间),Grover 削弱 AES(密钥翻倍即可) |
| 紧迫性 | ”先收集后解密”威胁,长期机密数据需立即保护 |
| 格密码 | 基于 LWE/Module-LWE 困难问题,量子计算机无法有效解决 |
| NIST PQC | Kyber(密钥封装)、Dilithium(签名)、SPHINCS+(备用签名) |
| 密钥大小 | PQC 密钥比传统大 10-50 倍,这是量子安全的代价 |
| 混合方案 | ECDH+Kyber、ECDSA+Dilithium,过渡期推荐 |
| 密码学敏捷性 | 算法可替换、密钥格式可扩展、协议可协商 |
| 迁移路径 | 评估→测试→混合→纯 PQC,现在开始准备 |
| 协议影响 | TLS 握手增大 1-2KB,X.509 证书膨胀 10-90 倍 |
| 侧信道 | 格密码实现需常数时间 NTT、掩码、冗余计算 |
后量子迁移不是未来的事——“先收集后解密”攻击正在发生。如果你的数据需要保密超过 5 年,现在就应该使用混合方案(ECDH+Kyber)加密。
参考
- RFC 9180 — FrodoKEM Learning With Error Key Exchange
支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
部分信息可能已经过时






