4. 密钥的生命周期

密钥不是一锤子买卖。很多团队把密钥创建出来就扔那儿不管了,结果出事的时候才发现密钥已经过期,或者被不知道哪个人给删了。我个人习惯把密钥的生命周期分成五个阶段来管理,每个阶段都有对应的操作规范和自动化工具体系。你想想看,密钥从生到死,它经历的每一个状态都应该有明确的控制策略。

核心理念:密钥是有生命的。你对待它,应该像对待一张信用卡——知道什么时候激活、什么时候挂失、什么时候更换、什么时候销户。
密钥生命周期流程 ① 创建(CreateKey) ② 启用 / 禁用 ③ 轮换(自动 + 手动) ④ 计划删除(等待期) ⑤ 立即删除(Cancel) ⑥ 版本管理 等待期保护

4.1 密钥创建

创建密钥是第一步,但很多人第一步就踩坑。密钥创建不仅仅是发一条 API 调用,它涉及到密钥类型、用途、描述标签、权限绑定等一系列决策。

最常见的两种密钥类型:

  • 对称密钥(Symmetric Key):加密和解密用同一个密钥。我建议在大多数业务场景下优先用对称密钥——性能好,管理也简单。
  • 非对称密钥(Asymmetric Key):公钥加密、私钥解密。做数字签名或跨系统加密场景时很合适。我记得有一次排查一个跨云数据传输的问题,最后发现是密钥类型选错了,导致解密失败,折腾了整整一个下午。

创建时的几个关键参数:

参数说明我个人的建议
KeySpec密钥规格(AES_256 / RSA_2048 等)对称选 AES_256,非对称选 RSA_2048 就够了,更高的规格性价比不高
KeyUsage用途(ENCRYPT_DECRYPT / SIGN_VERIFY)不要把加密和签名混用同一个密钥
Origin密钥材料来源(KMS / EXTERNAL)能托管就托管,外部导入多了一层安全隐患
Tags标签(Environment、Owner、Purpose)强制打标签,否则审计时你会哭的
记得加上加密上下文:创建密钥时顺手绑定一个加密上下文(EncryptionContext),它能让每次加密操作都带上业务语义,防止密文被跨业务误用。

4.2 启用与禁用

密钥不是创建出来就自动启用的。你需要主动调用 EnableKey 或 DisableKey。

禁用状态下的密钥有一个重要表现:所有需要用到这个密钥的加解密操作都会被拒绝。这意味着你的业务会直接断掉。我在项目中遇到过这种事故——有人为了测试禁用了一个生产密钥,结果全站的加密服务停了十分钟。嗯,这里要注意:

  • 禁用前一定要确认没有业务依赖当前密钥进行实时加解密
  • 如果密钥只用于旧数据解密,可以禁用它,但不能删除
  • 启用/禁用操作是秒级生效的,没有缓冲期
不要滥用禁用操作:禁用不是删除。你禁用了一个密钥,依赖它的解密操作会失败,而不仅仅是停止加密。我曾经见过有人把禁用当作"暂停使用",结果酿成了线上事故。

4.3 密钥轮换

轮换说白了就是换钥匙。为什么需要轮换?因为一个密钥使用时间越长,泄露的风险就越大。KMS 支持两种轮换方式:

  1. 自动轮换(Automatic Rotation):KMS 每年自动生成一个新密钥版本,旧的版本保留用于解密历史数据。建议开启自动轮换,省心。
  2. 手动轮换(Manual Rotation):自己调用 CreateKey 生成新密钥,然后更新应用。适合合规要求比较严格的场景。

我个人习惯的做法是:在密钥创建时就开启自动轮换,设置一个轮换周期(通常是 1 年)。然后在每年轮换的时候,顺便检查一下旧密钥的解密日志——如果长时间没有解密请求,就可以考虑清理掉了。

方式优点缺点
自动轮换零运维,版本自动管理轮换周期固定,不能自定义
手动轮换完全可控,可随时触发需要自己维护版本映射表,容易出错
小技巧:自动轮换只适用于对称密钥。如果你用的是非对称密钥,只能手动轮换。别问为什么,这是架构设计的历史包袱。

4.4 删除密钥:等待期与计划删除

这是最危险的操作。删除密钥是不可逆的——密文会彻底变成一堆二进制垃圾。所以 KMS 设计了一个等待期(PendingDeletionWindow)来保护你。

ScheduleKeyDeletion:

  • 调用后密钥进入 "待删除" 状态,状态变为 PendingDeletion
  • 默认等待 30 天(可设置 7~30 天)
  • 等待期内可以 CancelKeyDeletion 取消删除,密钥恢复到启用状态
  • 等待期结束后,密钥从系统中彻底消失,无法恢复

我曾经见到一个团队为了赶进度,直接把生产环境的密钥删了——好在 KMS 有等待期,他们在第 7 天发现了问题,赶紧取消了删除。如果那个密钥没有等待期,后果不堪设想。

永远不要在等待期内删除密钥:即使你 99% 确定密钥没用了,也等满整个等待期。旧密文可能会被沉睡的备份作业重新访问,那时候就追悔莫及了。

DeleteImportedKeyMaterial:这是另一种"伪删除"——只删除导入的密钥材料(External Key Material),但 KMS 的密钥容器还在。这种做法常用于合规审计:你可以清空密钥材料,但保留密钥的元数据和权限配置。

4.5 密钥版本管理

版本管理是 KMS 中一个容易被忽略但极其重要的概念。每次轮换或手动更新密钥,KMS 都会生成一个新的 密钥版本(KeyVersion)。

具体来说:

  • 每个密钥(Key)可以有多个版本(Version)
  • 每个版本对应一个唯一的密钥材料
  • 只有一个版本是 "当前版本",默认用于加密操作
  • 旧版本只用于解密历史数据,不能用于新加密

你想想看,如果你开启了自动轮换,那么你的密钥在一年后会有两个版本——一个旧的(用于解密),一个新的(用于加密)。三年后就有四个版本,以此类推。这就派生出两个重要设计原则:

  1. 不要依赖密钥版本做业务隔离:版本是自动递增的,你不能在应用代码里写死一个版本号
  2. 定期清理废旧版本:版本数过多会影响密钥的检索和性能(一般 KMS 支持最多 1000 个版本,但建议不要超过 100 个)
排查思路:当你的解密操作突然失败时,首先检查两个事情:① 密钥是否处于禁用状态 ② 正在使用的密钥版本是否已经过期。我排查过不下 20 次这类问题,60% 的原因都是版本过期。

4.6 小结与实践清单

这一章内容挺密实的,我来帮你画个重点。你以后碰到密钥生命周期的问题,直接照着这个清单走就行了:

阶段核心动作避坑指南(我曾经踩过的坑)
创建确定类型 / 用途 / 标签不要忽略 Tags,审计是逃不掉的
启用 / 禁用确认无业务依赖后再操作不要在高峰期禁用生产密钥
轮换对称用自动,非对称用手动自动轮换不能自定义周期,提前评估合规需求
删除走等待期,不要硬删我曾经手抖删了测试库密钥,还好有 7 天等待期救回来
版本管理定期清理、不写死版本号版本数太多会导致 API 响应变慢

最后一句大实话:密钥管理最大的敌人不是黑客,是懒。你只要在创建密钥时多花 5 分钟做好标签、开启自动轮换、设置好等待期,后面能省下无数时间和事故排查的心力。我自己吃过这个亏,所以现在每个密钥都按这个流程走,一点都不含糊。