2. 密钥管理基础与密码学回顾
说实话,很多安全架构搞到最后崩掉,根子都在密码学基础没打牢。密钥管理说白了就是保证密钥从生到死都安全。
我见过不少团队,算法选得挺高级,结果密钥就硬编码在代码里。嗯,这种架构神仙也救不了。
2.1 密钥是什么?
密钥就是一个参数。它配合密码算法,把明文变成密文,或者反过来。
核心观念:密码系统的安全性不依赖算法保密,而是依赖密钥保密。这就是Kerckhoffs原则。
- 对称密钥:加密和解密用同一个密钥。比如AES。我早年做支付系统时,就吃过对称密钥分发的苦头。
- 非对称密钥:公钥加密,私钥解密。比如RSA、ECC。适合密钥交换和数字签名。
2.2 密钥从哪里来?
生成密钥,最怕用伪随机数生成器(PRNG)且种子可预测。我在项目中遇到过,开发人员直接用 rand() 来生成密钥。结果呢?调试模式下种子固定,跑出来的密钥每次都一样。这密钥等于公开。
所以,一定要用密码学安全的随机数生成器(CSPRNG)。
// Python 示例,用 secrets 模块生成 AES-256 密钥
import secrets
aes_key = secrets._bytes(32) # 32 字节 = 256 位
print(aes_key.hex())
个人习惯:生产环境生成密钥,一定在HSM里操作。HSM自己产生的随机数,通常比操作系统提供的更可靠。
2.3 密码学基石速览
你不需要成为密码学专家,但下面这几个东西的原理得清楚。否则密钥边界设计就是瞎搞。
对称加密:AES
AES是目前主流。有128、192、256位三种密钥长度。我个人建议,新系统直接上256位。别纠结性能,那点差异在安全面前不值一提。
工作模式也要选对。我踩过CBC模式的坑——IV管理不好,加密就形同虚设。
// AES-256-GCM 加密示例(带关联数据)
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os
key = AESGCM.generate_key(bit_length=256) # 生成256位密钥
aesgcm = AESGCM(key)
nonce = os.urandom(12) # 推荐 12 字节随机数
ciphertext = aesgcm.encrypt(nonce, b"Hello, world!", None)
print(ciphertext.hex())
注意:AES-GCM 的 nonce 不能重复!我曾经见过测试环境 nonce 写死,导致密钥恢复攻击。这个坑,踩一次就够。
非对称加密:RSA 与 ECC
RSA密钥长,计算慢。ECC用更短的密钥实现同等安全度。现在趋势是ECC,因为IoT设备、移动端都对资源敏感。
| 安全等级 | RSA密钥长度 | ECC密钥长度 |
|---|---|---|
| 80位 | 1024位 | 160位 |
| 112位 | 2048位 | 224位 |
| 128位 | 3072位 | 256位 |
| 192位 | 7680位 | 384位 |
| 256位 | 15360位 | 512位 |
你想想看,RSA到256位安全等级要15360位,ECC只要512位。这差距太大了。
哈希与数字签名
哈希不用密钥,但它是签名的基础。SHA-256是目前最低标准。别用MD5、SHA-1了,它们这几年被撞得底裤都掉了。
数字签名呢,就是先对数据做哈希,然后用私钥加密这个哈希。验证时用公钥解密哈希,再对比。这套流程在代码签名、证书验证里天天用。
2.4 密钥生命周期管理
这是我工作中的重点。我把它拆成七个阶段。
- 生成:用CSPRNG,最好在HSM内生成。
- 分发:对称密钥的分发是最大难点。用非对称加密来保护对称密钥的传输。这就是混合加密。
- 存储:不能明文存储!用密钥加密密钥(KEK)来包裹存储密钥。或者直接放HSM里。
- 使用:限制密钥的使用范围。比如签名密钥只能签名,加密密钥只能加密。这在我做的PKI体系里是硬规矩。
- 轮换:密钥不能永久有效。我建议加密密钥每1-2年换一次。签名密钥如果私钥泄露,当场吊销。
- 备份:密钥丢失 = 数据丢失。必须加密备份,且备份密钥与主密钥物理隔离。
- 销毁:确保密钥彻底不可恢复。在HSM里销毁,或者用安全擦除工具覆写。
2.5 常见密钥管理误区
搞了这么多年安全架构,有些坑是大家反复踩的。
- 硬编码密钥:这个不用多说了,我在代码审查时看到一次打回一次。用密钥管理服务(KMS)或者HSM。
- 密钥不与基础设施集成:密钥管理应该自动化。手动在服务器间拷贝密钥文件,迟早出事。
- 忽略密钥轮换:密钥用十年不改,一旦泄露,所有历史数据全完。我曾在金融客户那里重构过整个密钥轮换体系,那叫一个痛苦。
- 混合加密选错:用RSA加密大文件数据?性能极差。正确的做法是:用RSA加密AES的密钥,然后用AES加密文件。
我曾经见过一个团队,把私钥存在Git仓库里。因为CI/CD需要用它来签包。嗯,那个仓库是公开的。发现的时候,数据泄露已经持续了半年。
2.6 给实战工程师的几点建议
- 从第一天就把密钥管理纳入架构。不要等上线了再补。补的东西通常不彻底。
- 优先选用云KMS或者硬件HSM。自己做密钥管理轮子,大概率出漏洞。我早期也觉得自己能做,后来发现专业的事交给专业工具。
- 所有密钥操作都要有审计。谁在什么时候用了哪个密钥?出了问题才查得出来。
- 多做分层。数据加密密钥(DEK)保护数据,密钥加密密钥(KEK)保护DEK。这样可以做到最小暴露。
密码学基础不难,难的是落地的时候不出疏漏。嗯,这一章把这些基础打牢了,后面讲密钥边界集成的时候,你才不会觉得虚。