量子计算对密码学的挑战#
2019 年,Google 宣布「量子霸权」:其量子计算机 Sycamore 用 200 秒完成了传统超级计算机需要 1 万年才能完成的任务。
虽然「量子霸权」本身没有直接威胁到密码学,但这个里程碑预示着一个不可忽视的未来:量子计算将使今天广泛使用的 RSA、ECC 等非对称加密算法变得不再安全。
这不仅是技术问题,更是关乎国家安全和商业机密的大事。
#一、量子计算的发展现状
#量子计算发展时间线
量子计算里程碑:
1994 - Shor 算法:量子计算机可以高效分解大整数
1996 - Grover 算法:量子搜索将搜索复杂度降低平方根
2001 - IBM 演示 7 量子比特量子计算机
2011 - D-Wave 推出商用量子计算机
2017 - IBM 推出 50 量子比特量子计算机
2019 - Google 声称量子霸权
2023 - IBM 发布 1121 量子比特系统
2024 - 错误纠正量子计算取得突破
预测:
- 2030 年代:可能破解 RSA-2048
- 2040 年代:大规模实用量子计算机#量子比特与经典比特的差异
经典比特 vs 量子比特:
经典比特:
┌─────────────────┐
│ 状态:0 或 1 │
└─────────────────┘
每次测量只能得到 0 或 1
量子比特:
┌─────────────────────────┐
│ │
│ |ψ⟩ = α|0⟩ + β|1⟩ │
│ │
│ α, β 是复数振幅 │
│ |α|² + |β|² = 1 │
│ │
└─────────────────────────┘
叠加态:可以同时是 0 和 1#量子计算机的威胁规模
威胁时间表预测:
2024 - 量子计算机状态:
- 约 1000 物理量子比特
- 错误率高,需要数千个物理量子比特实现 1 个逻辑量子比特
2028 - 预计:
- 约 10,000 物理量子比特
- 错误纠正改进
2030 - 预计(悲观):
- 约 1 百万物理量子比特
- 错误纠正基本解决
- 可破解 RSA-2048
2030 - 预计(乐观):
- 数百万物理量子比特
- 可破解 RSA-2048#二、Shor 算法对非对称加密的威胁
#Shor 算法原理
Shor 算法是由 Peter Shor 于 1994 年提出的量子算法,可以在多项式时间内分解大整数:
经典分解:
- 最优算法:General Number Field Sieve
- 复杂度:O(exp((log N)^(1/3)))
- RSA-2048 需要约 10^26 次操作
Shor 算法:
- 复杂度:O((log N)³)
- 量子比特需求:约 4000 个逻辑量子比特
- 相当于经典计算机约 10^12 年的计算量#为什么 RSA 不再安全
RSA 安全性基于:
n = p × q(两个大质数的乘积)
已知 n,求 p 和 q:
- 经典计算机:亚指数时间
- 量子计算机(Shor):多项式时间
Shor 算法步骤:
1. 选择随机数 x
2. 计算 gcd(x^r - 1, n)
3. 使用量子傅里叶变换 QFT 找到周期 r
4. 如果 r 是偶数,用 r 计算 p 和 q#对 ECC 的威胁
椭圆曲线离散对数问题:
已知 G(基点)和 Q = k × G,求 k
经典攻击:O(sqrt(n))
量子攻击(Shor 变体):O((log n)³)
ECC-256 相当于 RSA-2048 的安全性:
- 经典:需要约 2^128 次操作
- 量子:需要约 2^64 次操作
结论:ECC 同样被 Shor 算法威胁#三、Grover 算法对对称加密的威胁
#Grover 算法原理
Grover 算法是一种量子搜索算法,可以将无序数据库的搜索复杂度从 O(N) 降低到 O(sqrt(N)):
经典搜索:
- 搜索 2^256 个可能的密钥
- 需要平均 2^255 次尝试
- 相当于约 10^76 次操作
Grover 量子搜索:
- 需要约 2^128 次「量子查询」
- 约 10^38 次操作
- 相当于将密钥长度减半#对称加密的影响
| 算法 | 当前密钥长度 | 经典安全强度 | 量子安全强度 | 应对措施 |
|---|---|---|---|---|
| AES-128 | 128 位 | 128 位 | 64 位 | 升级到 AES-256 |
| AES-256 | 256 位 | 256 位 | 128 位 | 无需改变 |
| SHA-256 | 256 位 | 256 位 | 128 位 | 升级到 SHA-512 |
| SHA-512 | 512 位 | 512 位 | 256 位 | 无需改变 |
量子搜索对哈希的影响:
Grover 算法使哈希碰撞搜索从 O(2^n) 降低到 O(2^(n/2))
原本 SHA-256 的 256 位安全强度:
- 经典:2^256 次尝试
- 量子:2^128 次尝试
但 2^128 仍然是天文数字,实际上安全#四、后量子密码学概述
#什么是后量子密码学
后量子密码学(PQC)是指能够抵抗量子计算机攻击的密码学算法:
后量子密码学候选:
1. 基于格的密码学(Lattice-based)
- 安全性基于格问题的困难性
- 最被看好的方案
- 包括:CRYSTALS-Kyber, CRYSTALS-Dilithium
2. 基于哈希的签名(Hash-based)
- 安全性完全基于哈希函数
- 成熟可靠
- 包括:SPHINCS+
3. 基于编码的密码学(Code-based)
- 安全性基于纠错码问题
- 历史悠久
- 包括:Classic McEliece
4. 基于多变量的密码学(Multivariate)
- 基于多变量多项式问题
- 适合签名
- 包括:Rainbow
5. 同态加密(仍在研究中)
- 可在加密数据上计算
- 量子计算加速不明显#为什么格密码最被看好
格密码的优势:
1. 安全性基础坚实
- 格问题被认为是量子计算机也难以解决
- 长期密码学安全研究的基础
2. 效率高
- 密钥和签名相对较小
- 计算速度快
3. 多功能性
- 可以实现加密、签名、密钥交换
- 适合构建完整的密码系统
4. NIST 标准化选择:
- Kyber(密钥封装)
- Dilithium(签名)
- 都是基于格的算法#五、NIST 后量子密码标准化
#NIST 标准化进程
NIST PQC 标准化时间线:
2016 - NIST 启动后量子密码标准化进程
- 收到 82 个算法提案
- 筛选到 69 个进入评估
2017 - 第一轮评估
- 69 个算法参与
2019 - 第二轮评估
- 26 个算法进入
2020 - 第三轮评估
- 7 个算法进入决赛圈
2022 - 第一批标准发布
- CRYSTALS-Kyber(密钥封装)
- CRYSTALS-Dilithium(签名)
- SPHINCS+(签名)
- Classic McEliece(密钥封装)
2024 - 第二批标准
- FALCON(签名)
- BIKE, HQC(密钥封装)#已标准化的算法
PqcryptographyExamples.java
/**
* 后量子密码算法示例(使用 PQCrypto 库)
*/
// CRYSTALS-Kyber 密钥封装
public class KyberExample {
/**
* 生成 Kyber 密钥对
*/
public static KeyPair generateKyberKeyPair() {
// Kyber 提供三种安全级别:
// - Kyber512(相当于 AES-128)
// - Kyber768(相当于 AES-192)
// - Kyber1024(相当于 AES-256)
// 使用 Kyber768
byte[] publicKey = new byte[1184];
byte[] privateKey = new byte[2400];
KyberKeyGen.generate(publicKey, privateKey);
return new KeyPair(publicKey, privateKey);
}
/**
* Kyber 密钥封装
*/
public static byte[] encapsulate(byte[] publicKey) {
byte[] sharedSecret = new byte[32];
byte[] ciphertext = new byte[1088];
KyberEncaps.encapsulate(ciphertext, sharedSecret, publicKey);
// ciphertext 用于传输
// sharedSecret 作为共享密钥
return ciphertext;
}
/**
* Kyber 密钥解封装
*/
public static byte[] decapsulate(byte[] ciphertext, byte[] privateKey) {
byte[] sharedSecret = new byte[32];
KyberEncaps.decapsulate(sharedSecret, ciphertext, privateKey);
return sharedSecret;
}
}
// CRYSTALS-Dilithium 签名
public class DilithiumExample {
/**
* 生成 Dilithium 签名密钥对
*/
public static KeyPair generateDilithiumKeyPair() {
// Dilithium 提供三种安全级别:
// - Dilithium2
// - Dilithium3
// - Dilithium5
byte[] publicKey = new byte[1312];
byte[] privateKey = new byte[4000];
DilithiumKeyGen.generate(publicKey, privateKey);
return new KeyPair(publicKey, privateKey);
}
/**
* Dilithium 签名
*/
public static byte[] sign(byte[] message, byte[] privateKey) {
byte[] signature = new byte[2420];
DilithiumSign.sign(signature, message, privateKey);
return signature;
}
/**
* Dilithium 验签
*/
public static boolean verify(byte[] message, byte[] signature, byte[] publicKey) {
return DilithiumSign.verify(signature, message, publicKey);
}
}#算法对比
| 算法 | 类型 | 公钥大小 | 密文/签名大小 | 安全性 |
|---|---|---|---|---|
| Kyber768 | KEM | 1184 字节 | 1088 字节 | 192 位 |
| Dilithium3 | 签名 | 1952 字节 | 3293 字节 | 192 位 |
| SPHINCS+-128s | 签名 | 32 字节 | 7856 字节 | 128 位 |
| Classic McEliece | KEM | 1,048,575 字节 | 1568 字节 | 256 位 |
#六、CRYSTALS-Dilithium 详解
#Dilithium 算法原理
Dilithium 是基于格中 Module-LWE 问题的数字签名算法:
Module-LWE 问题:
给定:
- 矩阵 A(公开)
- 向量 b = As + e(模 q)
其中 s 是随机小向量(私钥)
其中 e 是随机小错误向量
求:
- s(短向量)
这被认为是即使量子计算机也难以解决的问题#Dilithium 结构
DilithiumStructure.java
/**
* Dilithium 签名流程
*/
public class DilithiumSigning {
/**
* Dilithium 签名(简化版)
*/
public static byte[] sign(byte[] message, byte[] privateKey) {
// 1. 从私钥提取 A, s1, s2, t
// A: 公共矩阵 (k × l)
// s1, s2: 私钥中的短向量
// t: 公钥向量
// 2. 采样随机向量 y
// y1: l 维随机向量
// y2: k 维随机向量
// 3. 计算 w = Ay(仅高比特位)
// w = Ay mod q
// 4. 计算哈希 c = H(seed || w_h)
// w_h: w 的高比特位
// 5. 计算 z = y + c * s1
// s1: 私钥中的短向量
// 6. 检查 ||z|| 是否有界
// 如果无界,返回步骤 2
// 7. 计算 c * t - y2 并检查低比特位
// r1: 低比特位
// r2: 高比特位 - c * t2
// 8. 输出签名 (z, c, r1)
return null; // 简化示例
}
/**
* Dilithium 验证
*/
public static boolean verify(byte[] message, byte[] signature, byte[] publicKey) {
// 1. 从签名提取 (z, c, r1)
// 2. 检查 ||z|| 有界
// 3. 计算 w' = Ay - c * t + c * r2
// 其中 r2 从 r1 计算
// 4. 计算 c' = H(seed || w'_h)
// 5. 比较 c == c'
return false;
}
}#七、迁移到后量子密码的挑战
#技术挑战
迁移挑战:
1. 密钥和签名大小
- RSA-2048 签名:256 字节
- Dilithium3 签名:3293 字节(12x)
- Kyber768 公钥:1184 字节
影响:网络带宽、存储、证书大小
2. 计算性能
- PQC 算法通常比传统算法慢
- 需要硬件加速支持
3. 互操作性
- 新旧系统需要共存
- 需要混合模式
4. 密钥管理
- 新的密钥类型
- 新的存储要求#迁移策略
HybridMigrationStrategy.java
@Service
@Slf4j
public class HybridCryptographyMigration {
/**
* 混合加密模式(推荐迁移策略)
*/
public static class HybridEncryption {
/**
* 混合加密:同时使用传统算法和 PQC 算法
*/
public static EncryptedData hybridEncrypt(
byte[] plaintext,
PublicKey traditionalKey,
PublicKey pqKey) throws Exception {
// 1. 生成随机对称密钥 DEK
byte[] dek = generateRandomKey(32);
// 2. 用对称密钥加密数据
byte[] ciphertext = encryptWithAes(plaintext, dek);
// 3. 用传统非对称密钥加密 DEK
byte[] encryptedDekTraditional = encryptWithTraditional(dek, traditionalKey);
// 4. 用 PQC 密钥加密 DEK
byte[] encryptedDekPqc = encapsulateWithKyber(dek, pqKey);
// 5. 返回组合结果
return new EncryptedData(
ciphertext,
encryptedDekTraditional,
encryptedDekPqc
);
}
/**
* 混合解密(任一算法成功即可)
*/
public static byte[] hybridDecrypt(
EncryptedData encryptedData,
PrivateKey traditionalPrivateKey,
byte[] kyberPrivateKey) throws Exception {
byte[] dek = null;
// 1. 尝试用传统算法解密
try {
dek = decryptWithTraditional(
encryptedData.getEncryptedDekTraditional(),
traditionalPrivateKey
);
} catch (Exception e) {
log.debug("传统算法解密失败");
}
// 2. 如果失败,尝试 PQC 解密
if (dek == null) {
dek = decapsulateWithKyber(
encryptedData.getEncryptedDekPqc(),
kyberPrivateKey
);
}
// 3. 用 DEK 解密数据
return decryptWithAes(encryptedData.getCiphertext(), dek);
}
}
/**
* 混合签名模式
*/
public static class HybridSignature {
public static byte[] hybridSign(
byte[] message,
PrivateKey traditionalKey,
byte[] dilithiumPrivateKey) throws Exception {
// 1. 用传统算法签名
byte[] traditionalSig = signWithTraditional(message, traditionalKey);
// 2. 用 Dilithium 签名
byte[] pqSig = signWithDilithium(message, dilithiumPrivateKey);
// 3. 组合签名
return combineSignatures(traditionalSig, pqSig);
}
public static boolean hybridVerify(
byte[] message,
byte[] combinedSignature,
PublicKey traditionalKey,
byte[] dilithiumPublicKey) throws Exception {
// 分离签名
SignaturePair sigs = splitSignatures(combinedSignature);
// 验证两者
boolean traditionalValid = verifyWithTraditional(
message, sigs.traditional, traditionalKey);
boolean pqValid = verifyWithDilithium(
message, sigs.pqc, dilithiumPublicKey);
// 两者都有效才算通过
return traditionalValid && pqValid;
}
}
}#八、企业应对策略
#时间规划框架
┌─────────────────────────────────────────────────────────────────┐
│ 企业 PQC 迁移时间线 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 立即行动(现在): │
│ - 盘点密码学资产 │
│ - 评估量子风险 │
│ - 制定迁移计划 │
│ │
│ 2024-2025: │
│ - 开始试点 PQC 算法 │
│ - 升级到 AES-256(量子安全) │
│ - 部署混合模式 │
│ │
│ 2026-2028: │
│ - 全面部署 PQC │
│ - 完成历史数据重新加密 │
│ - 关闭传统算法 │
│ │
│ 关键原则: │
│ - 「先收集,后解密」数据需要优先迁移 │
│ - 生命周期长的数据优先 │
│ - 配合密钥轮转进行 │
│ │
└─────────────────────────────────────────────────────────────────┘#分阶段迁移计划
PqcMigrationPlan.java
@Service
@Slf4j
public class PqcMigrationPlan {
/**
* 密码学资产盘点
*/
public Map<String, CryptoAsset> inventory() {
Map<String, CryptoAsset> assets = new HashMap<>();
// 1. TLS 证书和密钥
for (Certificate cert : certificateRepository.findAll()) {
CryptoAsset asset = CryptoAsset.builder()
.id(cert.getId())
.type(AssetType.CERTIFICATE)
.algorithm(cert.getAlgorithm())
.keyLength(cert.getKeyLength())
.dataClassification(cert.getDataClassification())
.lifetimeYears(cert.getRemainingValidityYears())
.build();
assets.put(cert.getId(), asset);
}
// 2. 加密密钥
for (EncryptionKey key : keyRepository.findAll()) {
CryptoAsset asset = CryptoAsset.builder()
.id(key.getId())
.type(AssetType.ENCRYPTION_KEY)
.algorithm(key.getAlgorithm())
.keyLength(key.getKeyLength())
.dataClassification(key.getDataClassification())
.lifetimeYears(key.getRemainingLifetimeYears())
.build();
assets.put(key.getId(), asset);
}
// 3. 签名密钥
for (SigningKey key : signingKeyRepository.findAll()) {
CryptoAsset asset = CryptoAsset.builder()
.id(key.getId())
.type(AssetType.SIGNING_KEY)
.algorithm(key.getAlgorithm())
.keyLength(key.getKeyLength())
.purpose(key.getPurpose())
.build();
assets.put(key.getId(), asset);
}
return assets;
}
/**
* 风险评估
*/
public RiskAssessment assessQuantumRisk(Map<String, CryptoAsset> assets) {
RiskAssessment assessment = new RiskAssessment();
for (CryptoAsset asset : assets.values()) {
QuantumRisk risk = QuantumRisk.LOW;
// 高敏感数据 + 长生命周期 = 高风险
if (asset.getDataClassification() == DataClassification.RESTRICTED
&& asset.getLifetimeYears() > 5) {
risk = QuantumRisk.HIGH;
}
// 高敏感数据 = 中风险
else if (asset.getDataClassification() == DataClassification.RESTRICTED) {
risk = QuantumRisk.MEDIUM;
}
// 非对称加密算法 = 高风险
else if (asset.getType() == AssetType.CERTIFICATE
&& isAsymmetric(asset.getAlgorithm())) {
risk = QuantumRisk.HIGH;
}
assessment.addAssetRisk(asset.getId(), risk);
}
return assessment;
}
/**
* 迁移计划
*/
public MigrationPlan createMigrationPlan(RiskAssessment assessment) {
MigrationPlan plan = new MigrationPlan();
// 按优先级分组
List<String> urgent = assessment.getHighRiskAssets();
List<String> medium = assessment.getMediumRiskAssets();
List<String> low = assessment.getLowRiskAssets();
// 阶段 1:紧急迁移(高风险)
plan.addPhase(MigrationPhase.builder()
.name("紧急迁移")
.assets(urgent)
.targetAlgorithm("Hybrid (EC + Kyber)")
.deadline(Instant.now().plus(Duration.ofDays(180)))
.build());
// 阶段 2:标准迁移(中风险)
plan.addPhase(MigrationPhase.builder()
.name("标准迁移")
.assets(medium)
.targetAlgorithm("Kyber/Dilithium")
.deadline(Instant.now().plus(Duration.ofDays(365)))
.build());
// 阶段 3:收尾(低风险)
plan.addPhase(MigrationPhase.builder()
.name("收尾")
.assets(low)
.targetAlgorithm("Post-Quantum Only")
.deadline(Instant.now().plus(Duration.ofDays(730)))
.build());
return plan;
}
}#思考题
问题 1:假设你的组织有大量使用 RSA-2048 加密的敏感数据,加密数据的有效期是 20 年。根据量子计算的发展预测,你应该在什么时候开始迁移到后量子密码?迁移的优先级如何确定?
参考答案
迁移时机分析:
「现在收集,以后解密」威胁:
攻击者可能:
1. 今天收集所有加密通信
2. 等待量子计算机成熟
3. 在未来某个时间解密
「收获现在,解密以后」(Harvest Now, Decrypt Later) 攻击
时间线:
- 今天:攻击者收集加密数据
- 2030-2040 年:量子计算机可能足够强大
- 2044+ 年:数据仍需保密
结论:数据保密期超过 2030 年的,现在就需要考虑迁移迁移时机决策树:
数据保密期分析:
数据保密期 = 当前年份 + 需要保密的年数
判断标准:
├─ 数据保密期 > 2030 年?
│ ├─ 是 → 立即开始迁移评估
│ └─ 否 → 2030 年前完成迁移
│
├─ 数据属于「关键基础设施」?
│ ├─ 是 → 立即迁移
│ └─ 否 → 按计划迁移
│
└─ 数据涉及国家安全/核心机密?
├─ 是 → 立即迁移
└─ 否 → 按优先级迁移优先级确定方法:
MigrationPriority.java
/**
* 迁移优先级计算
*/
public class MigrationPriority {
/**
* 优先级分数(越高越优先)
*/
public int calculatePriority(CryptoAsset asset) {
int score = 0;
// 1. 保密期限(最重要的因素)
int remainingYears = asset.getRemainingConfidentialityYears();
if (remainingYears >= 20) score += 50;
else if (remainingYears >= 10) score += 40;
else if (remainingYears >= 5) score += 30;
else if (remainingYears >= 2) score += 20;
else score += 10;
// 2. 数据敏感度
switch (asset.getDataClassification()) {
case RESTRICTED: score += 30; break;
case CONFIDENTIAL: score += 20; break;
case INTERNAL: score += 10; break;
case PUBLIC: score += 0; break;
}
// 3. 算法脆弱性
if (asset.getAlgorithm().isAsymmetric()) {
score += 20; // 非对称加密最脆弱
}
// 4. 业务影响
if (asset.isBusinessCritical()) score += 15;
if (asset.hasExternalExposure()) score += 10;
// 5. 迁移难度
int complexityPenalty = assessMigrationComplexity(asset);
score -= complexityPenalty; // 复杂系统降低优先级
return score;
}
/**
* 优先级分组
*/
public PriorityGroup classifyAsset(int priorityScore) {
if (priorityScore >= 80) return PriorityGroup.CRITICAL;
if (priorityScore >= 60) return PriorityGroup.HIGH;
if (priorityScore >= 40) return PriorityGroup.MEDIUM;
return PriorityGroup.LOW;
}
}迁移时间表建议:
┌─────────────────────────────────────────────────────────────────┐
│ 建议迁移时间表 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 高优先级(立即开始): │
│ - 保密期超过 15 年的数据 │
│ - 政府和军事数据 │
│ - 医疗健康数据 │
│ - 金融核心数据 │
│ - 知识产权和商业机密 │
│ 时间:现在开始,2 年内完成 │
│ │
│ 中优先级(2024-2025): │
│ - 保密期 5-15 年的数据 │
│ - 员工个人信息 │
│ - 合同和法律文档 │
│ 时间:2024-2025 年完成 │
│ │
│ 低优先级(2025-2027): │
│ - 保密期 2-5 年的数据 │
│ - 一般业务数据 │
│ 时间:2025-2027 年完成 │
│ │
│ 立即行动(无论优先级): │
│ - 升级对称加密到 AES-256 │
│ - 升级哈希到 SHA-384 或 SHA-512 │
│ - 制定完整的迁移计划 │
│ │
└─────────────────────────────────────────────────────────────────┘问题 2:设计一个混合密码系统,同时使用传统算法和后量子算法,确保:
- 即便量子计算机攻破了其中一种算法,数据仍然安全
- 与现有系统保持向后兼容
- 可以渐进式迁移到纯后量子系统
参考答案
混合密码系统设计:
设计原则:
1. 双重保护
- 数据必须同时被传统算法和 PQC 算法保护
- 攻击者需要同时破解两种算法
2. 向后兼容
- 支持纯传统模式
- 支持混合模式
- 支持纯 PQC 模式
3. 平滑迁移
- 新数据使用最强保护
- 旧数据逐步迁移
- 系统自动适应对方能力系统架构:
HybridCryptoSystem.java
@Service
@Slf4j
public class HybridCryptoSystem {
/**
* 运行模式
*/
public enum OperationMode {
/**
* 仅传统算法(向后兼容)
*/
TRADITIONAL_ONLY,
/**
* 混合模式(推荐初始阶段)
*/
HYBRID,
/**
* 仅 PQC(未来目标)
*/
POST_QUANTUM_ONLY,
/**
* 自动模式(根据对方能力选择)
*/
AUTO
}
/**
* 混合加密结果
*/
public static class HybridEncryptedData {
private final byte[] ciphertext; // 数据密文
private final EncryptedKey encryptedTraditionalKey; // 传统算法加密的密钥
private final EncryptedKey encryptedPqcKey; // PQC 算法加密的密钥
private final byte[] nonce; // 随机数
// 元数据
private final OperationMode mode;
private final String algorithmSuite;
}
/**
* 混合加密
*/
public HybridEncryptedData encryptHybrid(
byte[] plaintext,
EncryptionKey traditionalKey,
KyberPublicKey pqKey,
OperationMode mode) throws Exception {
// 1. 生成数据加密密钥
byte[] dek = generateRandomKey(32);
// 2. 用 DEK 加密数据(使用 AES-256-GCM)
byte[] nonce = generateNonce(12);
byte[] ciphertext = encryptAesGcm(plaintext, dek, nonce);
EncryptedKey encryptedTraditionalKey = null;
EncryptedKey encryptedPqcKey = null;
switch (mode) {
case HYBRID:
// 3a. 用传统算法加密 DEK
encryptedTraditionalKey = encryptWithTraditional(dek, traditionalKey);
// 3b. 用 PQC 算法加密 DEK
encryptedPqcKey = encapsulateWithKyber(dek, pqKey);
break;
case TRADITIONAL_ONLY:
// 仅传统加密
encryptedTraditionalKey = encryptWithTraditional(dek, traditionalKey);
break;
case POST_QUANTUM_ONLY:
// 仅 PQC 加密
encryptedPqcKey = encapsulateWithKyber(dek, pqKey);
break;
case AUTO:
// 根据密钥可用性自动选择
if (pqKey != null && traditionalKey != null) {
return encryptHybrid(plaintext, traditionalKey, pqKey, HYBRID);
} else if (pqKey != null) {
return encryptHybrid(plaintext, traditionalKey, pqKey, POST_QUANTUM_ONLY);
} else {
return encryptHybrid(plaintext, traditionalKey, pqKey, TRADITIONAL_ONLY);
}
}
return new HybridEncryptedData(
ciphertext,
encryptedTraditionalKey,
encryptedPqcKey,
nonce,
mode,
determineAlgorithmSuite(mode)
);
}
/**
* 混合解密
*/
public byte[] decryptHybrid(
HybridEncryptedData encryptedData,
EncryptionKey traditionalKey,
KyberPrivateKey pqKey) throws Exception {
byte[] dek = null;
switch (encryptedData.getMode()) {
case HYBRID:
// 尝试两种解密方式
try {
dek = decapsulateWithKyber(
encryptedData.getEncryptedPqcKey(), pqKey);
} catch (Exception e) {
log.debug("PQC 解密失败,尝试传统算法");
}
if (dek == null) {
dek = decryptWithTraditional(
encryptedData.getEncryptedTraditionalKey(),
traditionalKey);
}
break;
case TRADITIONAL_ONLY:
dek = decryptWithTraditional(
encryptedData.getEncryptedTraditionalKey(),
traditionalKey);
break;
case POST_QUANTUM_ONLY:
dek = decapsulateWithKyber(
encryptedData.getEncryptedPqcKey(), pqKey);
break;
}
// 用 DEK 解密数据
return decryptAesGcm(encryptedData.getCiphertext(), dek, encryptedData.getNonce());
}
}迁移支持:
MigrationSupport.java
@Service
@Slf4j
public class HybridCryptoMigration {
/**
* 检测对方的加密能力
*/
public Capabilities detectPeerCapabilities(Peer peer) {
Capabilities caps = new Capabilities();
// 1. 尝试协商 PQC
KyberPublicKey pqKey = peer.getKyberPublicKey();
caps.setSupportsPqc(pqKey != null);
// 2. 检测传统能力
caps.setSupportsTraditional(peer.hasTraditionalKey());
// 3. 返回支持的最优模式
if (caps.supportsPqc() && caps.supportsTraditional()) {
caps.setPreferredMode(OperationMode.HYBRID);
} else if (caps.supportsPqc()) {
caps.setPreferredMode(OperationMode.POST_QUANTUM_ONLY);
} else {
caps.setPreferredMode(OperationMode.TRADITIONAL_ONLY);
}
return caps;
}
/**
* 渐进式迁移
*/
public void migrateExistingData(DataMigrationPlan plan) {
// 1. 识别需要迁移的数据
List<EncryptedData> toMigrate = findDataNeedingMigration();
// 2. 按优先级排序
toMigrate.sort(Comparator.comparing(
EncryptedData::getDataClassification).reversed());
// 3. 分批重新加密
for (EncryptedData data : toMigrate) {
try {
// 读取旧数据
byte[] plaintext = readData(data);
// 用新模式重新加密
HybridEncryptedData newEncrypted = encryptHybrid(
plaintext,
plan.getNewTraditionalKey(),
plan.getNewPqKey(),
OperationMode.HYBRID
);
// 保存新数据
saveData(data.getId(), newEncrypted);
// 删除旧数据(可选)
if (plan.isDeleteOldAfterMigration()) {
deleteOldData(data);
}
log.info("数据迁移完成: {}", data.getId());
} catch (Exception e) {
log.error("数据迁移失败: {}", data.getId(), e);
recordMigrationFailure(data.getId(), e);
}
}
}
}安全属性分析:
混合加密的安全证明:
假设:
- 传统算法被量子计算机攻破
- PQC 算法保持安全
结论:
- 攻击者需要破解 PQC 算法才能获取密钥
- 因为 PQC 仍然安全,数据保持机密
反之亦然:
- 如果 PQC 被攻破,传统算法仍然安全
- (假设传统算法在经典计算机上安全)
混合方案的安全性 ≥ max(传统安全性, PQC安全性)