非对称加密简介
非对称加密(也称为公钥加密)是现代数字安全的基石。与共享单个密钥的对称加密不同,非对称系统使用一对密钥:用于加密或签名验证的公钥,以及用于解密或签名的私钥。
本指南探讨了从传统 RSA 到现代椭圆曲线加密 (ECC) 的演变,涵盖了 Ed25519、X25519 等标准以及 RSA-PSS 和 HKDF 等高级方案。
1. RSA 变体:OAEP, PSS 和 PKCS1-v1.5
RSA (Rivest–Shamir–Adleman) 数十年来一直是行业标准。然而,RSA 的实现方式对安全性有着重大影响。
RSA-PKCS1-v1.5(遗留标准)
最古老的填充方案。虽然仍广泛使用,但它容易受到填充预言机攻击(如 Bleichenbacher 攻击)。通常不建议在新的应用程序中使用。
RSA-OAEP (最优非对称加密填充)
用于加密。OAEP 添加了基于 Feistel 网络的填充,提供了“明文感知”能力。它防止攻击者能够修改密文并获取有关明文的信息。
- 建议:使用 RSA-OAEP 代替 PKCS1-v1.5 进行数据加密。
RSA-PSS (概率签名方案)
用于数字签名。与旧方案不同,PSS 在随机预言机模型中被证明是安全的。它在签名过程中添加了盐值,使其具有概率性而非确定性。
- 建议:现代协议(如 TLS 1.3)要求或强烈倾向于使用 RSA-PSS,而不是旧的 PKCS1-v1.5 签名。
2. 椭圆曲线加密 (ECC) 深度解析
ECC 提供与 RSA 相同的安全级别,但密钥更短。例如,256 位 ECC 密钥大致相当于 3072 位 RSA 密钥。
ECDSA (椭圆曲线数字签名算法)
数字签名算法 (DSA) 的椭圆曲线对应版本。
- ECDSA-P256:最常见的 NIST 曲线。虽然受到广泛支持,但由于 NIST 参数可能存在“后门”,一些人表示担忧。
- ECDSA-P384:用于更高的安全级别(绝密)。
EdDSA 和扭曲爱德华兹曲线
现代密码学正朝着 EdDSA (爱德华兹曲线数字签名算法) 方向发展。
- Ed25519:基于 Curve25519。它旨在实现高速和高安全性。它是确定性的(签名期间不需要随机数生成器),这消除了 ECDSA 中常见的灾难性故障源。
- Ed448:一种“金发姑娘”曲线,提供比 Ed25519 更高的安全性(224 位安全级别)。
3. 密钥交换协议
两个通信方如何在不安全的信道上建立共享密钥?
Diffie-Hellman (DH)
原始的密钥交换协议。今天,它大多已被其椭圆曲线版本取代。
ECDH (椭圆曲线 Diffie-Hellman)
- ECDH-P256 / P384:使用 NIST 曲线建立秘密。
- X25519:现代密钥交换的黄金标准。它是使用 Curve25519 的 ECDH 函数。与 NIST 曲线相比,它速度更快、更安全,且更易于正确实现。
- X448:X25519 的更高安全性对应版本。
4. 密钥衍生:HKDF
一旦建立了共享密钥(例如,通过 X25519),就不应直接将其用作加密密钥。相反,我们使用密钥衍生函数 (KDF)。
HKDF-SHA256 (基于 HMAC 的提取和扩展 KDF)
HKDF 遵循两步过程:
- 提取:获取“原始”共享密钥和一些可选盐值,以产生“伪随机密钥” (PRK)。
- 扩展:将该 PRK 转换为所需长度的多个密钥(例如,AES 密钥和 IV)。
使用 HKDF-SHA256 可确保最终生成的密钥具有强大的加密强度且相互独立。
5. 对比表
| 算法 | 密钥大小 (安全) | 性能 | 标准 | 场景 |
|---|---|---|---|---|
| RSA 2048 | 112-位 | 慢 | 遗留 | 兼容性 |
| RSA 3072 | 128-位 | 极慢 | 强 | 遗留/企业 |
| ECDSA-P256 | 128-位 | 快 | NIST | 通用移动端/Web |
| Ed25519 | 128-位 | 极快 | 现代 | 建议用于签名 |
| X25519 | 128-位 | 极快 | 现代 | 建议用于密钥交换 |
| Ed448 | 224-位 | 中等 | 高安全 | 超安全系统 |
6. 安全建议:为什么选择 Ed25519?
为什么专家们正从 RSA 和 NIST 曲线转向 Ed25519?
- 抗侧信道攻击:Ed25519 的实现通常在设计上是恒定时间的,可以防止计时攻击。
- 无“坏运气”随机性:ECDSA 每次签名都需要一个新的、高质量的随机数。如果 RNG 出现微小故障,你的私钥可能会被恢复。Ed25519 是确定性的,完全避免了这个问题。
- 性能:Ed25519 在签名和验证方面的速度显著更快,这对于高流量服务器至关重要。
- 短密钥:32 字节密钥在 QR 码、数据库索引和头部中比 512 字节 RSA 密钥更容易处理。
7. 代码示例
Node.js: Ed25519 签名
使用内置的 crypto 模块:
const crypto = require('crypto');
// 生成 Ed25519 密钥对
const { privateKey, publicKey } = crypto.generateKeyPairSync('ed25519');
const message = Buffer.from('Hello, Security!');
// 签名
const signature = crypto.sign(null, message, privateKey);
// 验证
const isVerified = crypto.verify(null, message, publicKey, signature);
console.log('签名验证结果:', isVerified);
Python: X25519 密钥交换
使用 cryptography 库:
from cryptography.hazmat.primitives.asymmetric import x25519
# Alice 端
alice_private = x25519.X25519PrivateKey.generate()
alice_public = alice_private.public_key()
# Bob 端
bob_private = x25519.X25519PrivateKey.generate()
bob_public = bob_private.public_key()
# 计算共享密钥
alice_shared = alice_private.exchange(bob_public)
bob_shared = bob_private.exchange(alice_public)
assert alice_shared == bob_shared
print("共享密钥已建立!")
8. FAQ: 常见陷阱
Q: 我可以为 RSA-OAEP 和 RSA-PSS 使用同一个密钥吗?
A: 技术上可行,但强烈建议不要这样做。将同一个密钥用于不同的目的(加密和签名)可能会导致跨协议攻击。始终针对不同的角色使用独立的密钥。
Q: Ed25519 能抵抗量子攻击吗?
A: 不能。 与 RSA 和目前所有的 ECC 一样,Ed25519 容易受到使用 Shor 算法的大规模量子计算机的攻击。为了实现量子抗性,你应该研究后量子密码学 (PQC),如 ML-KEM 或 ML-DSA。
Q: 为什么在 HKDF 中使用 SHA-256?
A: SHA-256 提供了很高的安全边际,并且在全球范围内得到支持。虽然 SHA-3 或 BLAKE2 也很出色,但 SHA-256 仍然是 HKDF 实现的行业标准。
总结
从 RSA 向椭圆曲线加密的转变代表了安全性和效率方面的巨大飞跃。对于现代应用:
- 使用 Ed25519 进行数字签名。
- 使用 X25519 进行密钥交换。
- 使用 HKDF-SHA256 进行密钥衍生。
- 仅在严格要求旧版兼容性时才使用 RSA-OAEP/PSS。
通过采用这些现代标准,你可以确保你的应用程序快速、安全,并符合当前的密码学最佳实践。