3. 创建与管理 KMS 密钥:控制台与 CLI 实践

密钥是 KMS 的核心资产。说白了,CMK(客户主密钥)就是一把「万能钥匙」——它不直接加密你的数据,而是保护其他数据密钥。我当年刚接触 KMS 时觉得这东西很玄乎,直到有一次线上事故:密钥误删导致整库加密文件无法解密……嗯,从那以后我对密钥生命周期管理格外小心。

3.1 通过控制台创建 CMK

登录云控制台,进入 KMS 服务页面。我个人习惯先看「密钥管理」菜单,这里能直观看到所有密钥的状态。

  1. 选择密钥类型:对称密钥还是非对称密钥?日常加密首选对称,公钥加密场景才用非对称。我在金融项目里遇到过合规要求,必须用非对称密钥做数字签名,这点要提前确认。
  2. 填写别名:建议用业务名+环境,比如 prod-payment-key,别偷懒起毫无意义的名称。
  3. 选择密钥材料来源:要么让 KMS 自动生成(省心),要么导入你自己的密钥材料(合规强控)。
  4. 设置权限策略:默认只给当前账号管理员权限,后面章节会细讲。
小经验:创建时勾选「自动轮转」,一年轮一次。我见过因为密钥轮转逾期导致安全审计不通过的惨案。

3.2 通过 CLI 创建 CMK

如果管理几百个密钥,控制台就太累了。用 CLI 脚本批量创建才是运维工程师的尊严。

# 创建对称 CMK
aws kms create-key \
  --description "Prod payment encryption key" \
  --key-usage ENCRYPT_DECRYPT \
  --origin AWS_KMS

# 创建非对称 CMK(用于签名)
aws kms create-key \
  --key-spec RSA_4096 \
  --key-usage SIGN_VERIFY

# 创建带标签和别名的密钥
aws kms create-alias \
  --alias-name alias/prod-payment-key \
  --target-key-id 1234abcd-12ab-34cd-56ef-1234567890ab

为什么要先建密钥再建别名?create-key 返回的 KeyId 是关联别名的唯一凭据。我踩过的一个坑是:直接对 KeyId 硬编码,后面每次轮转密钥后都要改脚本。用别名就灵活多了。

3.3 密钥别名管理

别名是 CMK 的「外号」,能让你在应用层不关心底层密钥的 ID 变化。别名可以随时指向另一个 CMK,实现无缝切换。

  • 创建别名:aws kms create-alias --alias-name alias/my-key --target-key-id <key-id>
  • 修改别名关联:aws kms update-alias --alias-name alias/my-key --target-key-id <new-key-id>
  • 删除别名:aws kms delete-alias --alias-name alias/my-key
注意:别名不能以 alias/aws/ 开头,那是 Amazon 托管密钥的保留命名空间。我曾经不小心用了 alias/aws/s3,结果 CLI 直接报错。

3.4 启用与禁用密钥

禁用密钥是临时「关掉」加密能力,不解密,不轮转。我曾在灰度发布中用到这个功能:先禁用旧密钥,观察应用是否触发异常,确认无误后再删除。

# 禁用
aws kms disable-key --key-id 1234abcd-12ab-34cd-56ef-1234567890ab

# 启用
aws kms enable-key --key-id 1234abcd-12ab-34cd-56ef-1234567890ab

禁用后的密钥处于 Disabled 状态,任何 Encrypt / Decrypt 操作都会失败。你会收到类似 KMSInvalidStateException 的异常——这实际上是好事,说明安全机制生效了。

3.5 计划删除密钥与等待期

千万别手软点「立即删除」!KMS 提供了「计划删除」机制:设置一个 7~30 天的等待期。这段时间内密钥处于 PendingDeletion 状态,你可以随时取消。

# 计划删除,等待期 14 天
aws kms schedule-key-deletion \
  --key-id 1234abcd-12ab-34cd-56ef-1234567890ab \
  --pending-window-in-days 14

# 取消删除
aws kms cancel-key-deletion --key-id 1234abcd-12ab-34cd-56ef-1234567890ab
关键提醒:等待期内 KMS 不会收取月费,但如果你使用了该 CMK 加密的密文,在密钥被真正销毁后将永远无法解密。我在客户那里见过生产环境误删密钥导致业务瘫痪的案例,事后回溯发现密文还在但密钥没了。所以计划删除前务必确认:是否还有任何密文依赖此密钥?建议先用 list-resource-tags 或审计日志搜索一下引用。

3.6 密钥状态流转图

下面是我自己画的一张状态图,帮你直观理解 CMK 的生命周期。说白了就是:创建→启用→禁用→再次启用→计划删除(等待期)→最终销毁。

CMK 密钥生命周期状态流转 创建 CMK 已启用 (Enabled) 已禁用 (Disabled) 计划删除 (PendingDeletion) 已销毁 (Deleted) 注意:等待期内可取消删除,密钥恢复为已启用状态;等待期满后密钥被永久销毁,无法恢复

3.7 密钥管理的避坑清单

操作 常见错误 我的建议
创建别名 别名与已有 CMK 冲突 用 list-aliases 先检查一次
计划删除 未检查关联资源就删除 先查 CloudTrail 日志确认近期解密操作
启用/禁用 禁用后应用报错才想起来 建议用金丝雀部署逐步切换
CLI 脚本 KeyId 写死,轮转后失效 一律用 alias/ 索引

再说一个我自己的小教训:以前做密钥轮转时,创建了新密钥但忘记更新别名的指向,结果新数据用了新密钥,旧数据还在旧密钥下,审计日志里混乱不堪。后来我写了一个脚本,每次轮转自动执行「创建新密钥 → 更新别名 → 禁用旧密钥」三步走,再也没出过乱子。

不要做的操作:在生产环境直接 delete-key(如果服务商支持)。KMS 的 schedule-key-deletion 就是用来保护你手滑的。哪怕运维再着急,也请至少设 7 天等待期。

嗯,这一节内容不少。理解密钥状态机的流转,加上控制台和 CLI 两种手段,日常管理基本够用了。后面要讲的权限策略和审计日志才是真正的「大菜」——它们决定了你的密钥能不能防住内部误操和外部攻击。