4. 密钥生成与存储安全:随机数生成标准、密钥存储介质、加密存储方法
密钥安全,说白了就是从诞生到躺平都不能出事。你想想看,要是密钥生成的那一刻就带着缺陷,后面再好的存储手段也白搭。我个人习惯把「生成」和「存储」看作一对双胞胎,谁都不能掉链子。
这一节,咱们就聊聊随机数到底怎么才算「真随机」、密钥该往哪里放、以及用什么办法加密才靠谱。
4.1 随机数生成标准——别让“随机”变成“伪随机”
PCI DSS 明确要求:密钥生成必须使用符合 FIPS 140-2 或同等标准的随机数生成器。为什么这么严格?因为很多所谓的「随机」其实是可以预测的。我就遇到过一家客户,用 C 语言的 rand() 生成密钥种子——你猜怎么着?同一个程序每次启动,前 10 个“随机数”完全一样。这要是被人拿到样本,密钥就等于白送了。
标准到底在管什么?核心就三点:
- 熵源质量——硬件噪声、热噪声、量子效应,而不是软件算法模拟出来的伪随机。
- 生成器状态不可预测——即使攻击者拿到当前输出,也无法反推过去或未来输出。
- 输出均匀性——0 和 1 出现的概率没有显著偏差。
在生产环境里,我最推荐的方案是:
| 场景 | 推荐随机数源 | 说明 |
|---|---|---|
| Linux 服务器 | /dev/urandom(已够用) |
熵池足够大,性能好;避免用 /dev/random 阻塞 |
| HSM / TPM | 内置硬件 TRNG | 硬件真随机,通过 FIPS 140-2 认证 |
| 云环境 | 云厂商 KMS 的随机数 API | 例如 AWS KMS 的 GenerateRandom,背后是硬件 TRNG |
| 嵌入式设备 | 专用安全芯片 RNG | 避免使用 MCU 内部振荡器模拟 |
srand(time(NULL))。曾经真有人用时间种子生成密钥,结果同一秒内创建的两个密钥完全相同。这种bug,审计一把就抓出来。
4.2 密钥存储介质——钥匙放在哪才安全?
密钥生成之后得有个地方存放。PCI DSS 对存储介质的要求很明确:不能把明文密钥直接塞进文件系统、数据库或者环境变量里。那放哪?我按安全等级排个序:
- 硬件安全模块(HSM)——金库级。密钥永远不出设备,所有运算都在内部完成。PCI PIN 和支付应用强制要求。
- 可信平台模块(TPM)——主板级。适合服务器整机加密,比如 BitLocker、LUKS 绑定 TPM。
- 安全元件(SE)——芯片级。手机、银行卡、POS 终端里常见。
- 密钥管理服务(KMS)——云原生级。AWS KMS、Azure Key Vault、阿里云 KMS 等。注意:云 KMS 本身底层还是 HSM。
为什么 HSM 最安全?我拆过一台老款 HSM 的防护外壳——里面灌了环氧树脂,一撬就破坏内部电路,密钥瞬间自毁。💣 嗯,这就是物理级的防护。
4.3 加密存储方法——双层锁拿什么做?
有些场景下你没法用 HSM(比如预算不够,或者密钥量太大),那怎么办?退而求其次,用加密保护密钥。但这里有个关键:你不能用同一个密钥去加密自己,必须分层。
标准做法是「密钥加密密钥(KEK)」模式:
- 主密钥(MK)——也叫根密钥,用 HSM 或 KMS 保护,千万不能明文落地。
- KEK——由主密钥加密后存储。每次使用 KEK 前,先让主密钥解密它。
- 工作密钥(DEK)——真正用于加解密数据的密钥,由 KEK 加密后持久化。
加密算法推荐:AES-256-GCM(带认证加密,能防篡改)。密钥长度至少 256 位,不要再用 3DES 或 RC4——这些已经被时代抛弃了。
下面是一个 KEK 模式的伪代码示意(仅用于理解逻辑,不是生产代码):
// 1. 主密钥(从 HSM 读取)
masterKey = hsm.unwrap("mk-id")
// 2. 用主密钥解密 KEK
encryptedKEK = readFromFile("kek.bin")
kek = aes256GcmDecrypt(masterKey, encryptedKEK)
// 3. 用 KEK 解密工作密钥
encryptedDEK = readFromDatabase("dek_ciphertext")
dek = aes256GcmDecrypt(kek, encryptedDEK)
// 4. 用工作密钥解密实际数据
plaintext = aes256GcmDecrypt(dek, ciphertext)
你发现没?整个链路里,只有主密钥是明文出现在内存中的(而且时间要尽量短)。KEK 和 DEK 在存储和传输时都是密文。这就是所谓的“一次一密,层层包裹”。
- 所有密钥加密必须使用 FIPS 140-2 认可的算法(AES、TDES 仅限遗留系统)。
- 加密密钥的密钥(KEK)必须与数据加密密钥(DEK)分开管理。
- 密钥备份必须加密,且备份介质与主介质异地存放。
4.4 流程总览:从生成到安全落地
为了让你更直观地理解,我画了一张简图。它涵盖了从随机数源、密钥生成、分层加密到最终存储的完整链路。你就按这个顺藤摸瓜去审计,每一步都盯着:
这张图你完全可以打印出来贴在工位上。每次做密钥审计的时候,拿着它对照一遍:从入口(随机数)到出口(备份),每个环节都不能漏。
好了,密钥生成和存储这一块,其实核心就三件事:用真随机、放对地方、套多层。你按这个思路去巡检,审计基本不会出大问题。