4. 非对称密钥对:RSA、ECC、密钥生成与存储要点
说到非对称密钥对,很多人第一反应就是“公钥加密、私钥解密”。但实际项目中,真正决定安全边界的,是密钥的生成和存储质量。我经手过不少密钥泄露的复盘,结果发现——
问题往往不在算法本身,而在生成时的随机数烂了,或者存储时私钥躺在一个任何人都能读的文件里。
嗯,这一章我们就把 RSA 和 ECC 掰开揉碎,说说生成和存储的那些关键点。
4.1 RSA 与 ECC:选谁?
在安全架构里,选 RSA 还是 ECC 不是一个学术问题,是一个工程权衡。我个人的经验是:
- RSA:兼容性好,几乎所有平台都支持,但密钥越长性能越差。2048 位是现在的底线,4096 位虽然更安全,但握手慢到你会怀疑人生。
- ECC:用更短的密钥达到同等安全强度,性能优势明显。但曲线参数选择是个坑,用错了反而更脆弱。
| 特性 | RSA (2048-bit) | ECC (P-256) |
|---|---|---|
| 密钥长度 | 2048 位 | 256 位 |
| 安全强度 | ~112 位 | ~128 位 |
| 签名速度 | 慢 | 快 |
| 验证速度 | 快 | 中等 |
| 硬件支持 | 普遍 | 需要确认 |
我的建议:新项目优先选 ECC(P-256 或 curve25519),除非你有遗留系统必须兼容 RSA。但不要自己去撸曲线参数,用 NIST 推荐或 RFC 7748 里的标准曲线。
4.2 密钥生成要点
生成非对称密钥对,本质是让计算机“随机”挑出一个私钥,然后算出对应的公钥。这里最容易被忽视的就是随机数质量。
- 随机数种子:必须用操作系统提供的密码学安全随机数生成器(如
/dev/urandom)。我曾经见过一个项目直接用rand()生成 RSA 私钥——结果每次重启后生成的密钥都一样,简直是请君入瓮。 - 素数检测 (RSA):RSA 依赖大素数,Miller–Rabin 检测要跑足够多的轮数。OpenSSL 默认 5 轮,我一般加码到 10 轮。
- 曲线参数校验 (ECC):生成 ECC 密钥后,要验证公钥是否在曲线上。有些库没做这个检查,导致攻击者可以通过无效曲线攻击收集私钥信息。
# 生成 RSA 2048 位私钥(推荐)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private.pem
# 生成 ECC P-256 私钥
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out ecdsa_private.pem
避坑指南:我曾经接手过一个系统,RSA 密钥生成时指定了 -rand 参数但 seed 文件一直没更新,导致所有实例的私钥相同。生成后务必检查私钥的模数是否唯一——做个简单的模数碰撞测试就能发现问题。
4.3 密钥存储要点
私钥一旦泄露,加密边界就不存在了。存储其实比生成更考验架构设计。
4.3.1 文件存储
- 权限:私钥文件 600,目录 700。别问我为什么见过 644 的私钥——问就是“方便测试”。
- 加密:明文密钥文件要避免在磁盘上长期存在。如果必须存,用加密文件系统(如 LUKS)。
- 格式:PEM 格式兼容性最好,但 Base64 编码容易复制泄露;DER 二进制更隐形,但跨平台麻烦。
4.3.2 硬件安全模块(HSM) / TPM
- HSM 是最安全的方式,私钥永远不出硬件。代价是贵、慢。
- TPM 是廉价替代方案,适合普通服务器。Windows 用 TPM,Linux 用 tpm2-tools。
- 密钥分割:如果需要多节点签名,可以用 Shamir 秘密共享将私钥分片,但管理复杂度上升。
4.3.3 密钥生命周期
- 轮换:RSA 密钥每年换一次,ECC 可以两年。但如果是短期会话密钥,生命周期以分钟计。
- 销毁:删除前用随机数覆盖文件区。别只
rm——磁盘扇区还能恢复。我记得有次做审计,发现服务器上还有 3 年前过期的私钥碎片。
核心原则:非对称密钥的私钥永远不应该离开它被生成的环境。如果必须导出,要用密码短语加密后再传输。公钥可以随意分发,但必须通过带外方式验证指纹。
知识体系:非对称密钥对的核心路径
还记得我开头说的复盘案例吗?那个系统 RSA 密钥生成用了 srand(time(NULL)),结果所有节点私钥完全一样。攻击者拿到一个证书就能解密整个集群的流量。教训就是:随机数质量 + 存储权限 = 密钥安全的两条腿,缺一不可。
好了,这一章的内容就到这儿。非对称密钥对不是你选个库就完事的——生成时的随机源、存储时的访问控制、周期性的轮换审计,每一环都要在安全架构里明确边界。