1. KMS 是什么?为啥我们要折腾跨账号共享?
说实话,我刚接触 AWS KMS 的时候,觉得它就是「一个存密钥的保险柜」。用的时候调个 API 加密,完事。后来在项目里做多账号架构的合规改造,才真正理解 KMS 的核心价值——它不只是存密钥,而是帮你把加密权限和密钥生命周期管起来。
这章我们先打地基。把 KMS 的基本概念、密钥分层、共享场景说明白。后面再动手配置跨账号,心里才不慌。
1.1 核心概念:主密钥 vs 数据密钥
AWS KMS 里有两个最重要的概念:客户主密钥(CMK)和数据密钥(Data Key)。很多人一开始会混淆,我踩过这个坑。
一句话总结:你直接管理的是 CMK,但真正用来加密数据的,是 CMK 生成的临时数据密钥。
为什么这么设计?你想想看,如果每个 S3 对象都用同一个固定的密钥去加密,密钥泄露就全完了。KMS 的做法是:你用 CMK 生成一个数据密钥,然后用这个数据密钥去加密实际数据。数据密钥用完可以丢掉,下次解密时再让 KMS 用 CMK 把数据密钥解密回来。
这就是信封加密(Envelope Encryption)的思路。AWS 大量服务(S3、EBS、RDS)都默认走这个模式。
| 概念 | 特点 | 生命周期 |
|---|---|---|
| 客户主密钥 (CMK) | 逻辑密钥,包含元数据、密钥材料、权限策略 | 长期存在,可以启用/禁用/轮换/删除 |
| 数据密钥 (Data Key) | 由 CMK 生成,明文+密文双版本 | 临时使用,用完可丢弃 |
我习惯把 CMK 理解成「保险柜的钥匙」,数据密钥是「保险柜里临时文件柜的钥匙」。你每天换文件柜钥匙,但保险柜钥匙不变。
1.2 密钥层级与别名
KMS 还支持别名(Alias),这是一个很贴心的设计。我早期在脚本里硬编码了密钥 ID,后来换了密钥,改代码改到崩溃。用别名就可以只更新别名指向,不动代码。
- 密钥 ID:UUID 格式,全局唯一。适合自动化脚本引用。
- ARN:资源名称,跨账号时一定要用 ARN 而不是 ID。
- 别名:alias/xxx,方便人类阅读,支持随时重映射。
另外,CMK 分为托管型和客户管理型。托管型是 AWS 服务帮你创建的(比如 S3 默认密钥),你不能直接改策略。跨账号共享场景下,你必须用客户管理型 CMK。
1.3 我这几年遇到的一个常见误解
有人会问:「我能不能直接把 CMK 的密钥材料导出,发给另一个账号?」
不行。KMS 的密钥材料默认是硬件安全模块(HSM)保护的,AWS 不允许你导出明文密钥材料。跨账号共享的正确姿势,是给目标账号授权使用你的 CMK,而不是把密钥材料复制过去。
千万注意:一旦你把 CMK 设为「不可导出」,它就是不可导出的。想换密钥?只能新建。所以创建 CMK 时就想清楚密钥材料来源(KMS 生成还是外部导入)。
1.4 跨账号共享为什么需要 KMS?
现实中,企业往往有多账号体系:生产账号、日志账号、审计账号。比如日志账号需要解密生产账号的 S3 加密日志,但如果每个账号各自用独立的 KMS 密钥,你没办法让日志账号直接看到生产账号的密文。
KMS 提供了两种跨账号机制:
- 密钥策略(Key Policy):在 CMK 层面直接授权其他账号的 IAM 角色或用户。
- 授权(Grant):临时、细粒度地赋予某个身份操作权限。
这两种方式就是我们后面章节要动手配置的核心。第1章先理解概念,心里有个谱。
我的经验:大多数生产场景用密钥策略就够了,配置清晰且持久。授权适合短期的跨账号操作,比如数据迁移期间临时开放权限。
1.5 一张图看懂 KMS 核心概念关系
下面这张图把 CMK、数据密钥、密钥策略、授权以及跨账号共享的关系串起来。我建议你先扫一眼,再回来细读各概念。
1.6 这章我们学到的关键点
- CMK 是逻辑密钥,不能直接导出其密钥材料。
- 数据密钥才是实际加密数据的密钥,由 CMK 临时生成。
- 跨账号共享依靠密钥策略或授权,不是复制密钥。
- 别名可以让密钥引用更灵活,建议养成用别名的习惯。
我建议你在账号里创建一个 alias/demo-key 的 CMK,用控制台试试「生成数据密钥」操作,看看返回的明文和密文结构。实践一次,概念就通了。