密钥服务核心功能:生成、存储、轮换、销毁

密钥服务的四个支柱——生成、存储、轮换、销毁——看似简单,每一条踩过的坑都能写一篇事故报告。我还在做内部密钥管理时,觉得轮换不就是换个新密钥吗?直到线上因轮换不及时导致解密失败,才明白这四个环节环环相扣,少一个都撑不起高可用。

密钥服务核心功能流程 密钥生成 密钥存储 密钥轮换 密钥销毁 ⚠ 四个环节必须形成闭环: 生成→存储→轮换→销毁,缺一不可 💡 轮换与销毁需要联动 旧密钥安全销毁后才能启用新密钥

1. 密钥生成——源头活水必须纯

密钥生成的本质是产生不可预测的随机数。我曾见过团队直接用 Math.random() 生成 AES 密钥,结果被安全审计直接打回。说白了,伪随机数生成器(PRNG)在密码学场景下根本不够格。你必须用密码学安全的随机数生成器(CSPRNG)。

个人习惯:生产环境我推荐使用 /dev/urandom(Linux)或操作系统提供的 CryptGenRandom(Windows)。哪怕性能要求高,也绝不用非密码学的 PRNG。

常见的密钥类型与生成方式对照:

密钥类型 推荐算法/标准 最小长度 生成来源
AES 对称密钥 AES-256 256 bit CSPRNG
RSA 非对称密钥对 RSA-3072 或更高 3072 bit openssl genpkey
ECDSA 签名密钥 P-256 / P-384 256 bit EC 曲线生成
HMAC 密钥 HMAC-SHA256 256 bit CSPRNG

我曾经踩过的坑:使用硬件安全模块(HSM)生成密钥时,忘记检查 HSM 的随机数源是否已经老化。结果生成了一批弱密钥,导致整个集群需要紧急轮换。切记:生成后要做随机性验证,比如 NIST SP 800-90B 的统计检测。

2. 密钥存储——藏好你的命根子

密钥生成只是第一步,怎么存、存哪里才是真正的考验。我见过最离谱的案例:有人把私钥直接硬编码在配置文件里,还上了 Git 仓库。这种事一旦发生,整个 CI/CD 流水线都要重建。

存储方案通常分三级:

  • 软件加密存储:将密钥加密后存入数据库或磁盘文件。性能高,但主密钥仍需要保护。
  • 专用密钥管理服务(KMS):云厂商或自建 KMS,密钥不出设备,API 调用使用。比如 AWS KMS、Vault。
  • 硬件安全模块(HSM):最高等级,密钥在 FIPS 140-2 Level 3 的硬件内生成、存储、操作。适合金融、政务场景。

存储时必须考虑的要素:

  • 加密存储(至少 AES-256-GCM)
  • 访问控制(最小权限原则,每个应用只能读自己需要的密钥)
  • 审计日志(谁、什么时间、读取了哪个密钥)
  • 密钥分层(主密钥 → 加密密钥 → 数据密钥)

我建议的存储实践:不要让应用直接持有主密钥。用 envelope encryption(信封加密),应用只持有数据密钥的密文,解密时由 KMS 或 HSM 完成解密。万一应用被入侵,攻击者拿到的也只是加密后的密钥。

3. 密钥轮换——不换就等着被晾干

轮换不是单纯的“换新密钥”,而是要在不停机、不丢数据的条件下完成密钥的平滑切换。你想想看,如果数据库的加密密钥突然换掉,所有已有数据怎么解密?这就是多活架构下最头疼的问题。

我的经验是按照**两阶段轮换**策略:

  1. 灰度阶段:新密钥生成后,系统同时支持旧密钥解密、新密钥加密。新数据用新密钥加密,旧数据仍用旧密钥解密。
  2. 回收阶段:确认所有旧数据已被重新加密或主动重写后,禁用旧密钥,保留一段时间用于灾难恢复。

自动轮换配置示例(基于 Vault + TTL):

# 设置密钥轮换周期为 30 天
vault write pki/roles/my-role \
    allowed_domains="example.com" \
    allow_subdomains=true \
    max_ttl="720h" \
    key_type="rsa" \
    key_bits=4096

# 触发立即轮换
vault write pki/issue/my-role common_name="svc.example.com" \
    ttl="24h"

轮换的几个常见避坑点:

  • 不要急着重用旧密钥 ID,防止缓存问题导致解密失败
  • 多活环境下,轮换消息需同步到所有站点,可以用 etcd 或 ZooKeeper 做分布式协调
  • 轮换过程中务必保留旧密钥至少一个“轮换窗口”(比如一个 TTL 时长)

4. 密钥销毁——入土为安也需要仪式

销毁不是删个文件那么简单。普通的 rm 只是删除引用,数据还在磁盘上,可以被工具恢复。我参与过一个合规审计,要求彻底销毁退役的 HSM 中的所有密钥,步骤包括:电刷写、物理破坏,最后还有第三方检测报告。

销毁方法按安全等级排列:

方法 安全等级 适用场景
覆写(overwrite) 中 软件密钥,单盘未共享
加密删除(crypto erase) 高 加密存储卷,销毁 DEK 即可使所有数据不可读
物理销毁(shredder / degauss) 极高 HSM、智能卡、SSD 颗粒

我曾经犯过的错:以为加密删除后旧密钥就消失了,结果忘记收回 KMS 中对该密钥的权限。后来一个运维人员误操作,用旧备份的密文数据 + 未被销毁的密钥竟然解密了部分数据。所以销毁不仅仅是销毁密钥本身,还要切断所有引用路径、权限和备份。

销毁后的验证同样重要:

  • 尝试调用原密钥解密,必须返回错误
  • 检查审计日志,确认销毁操作已被记录
  • 多活环境下,确认所有站点的密钥副本均已销毁