“密钥轮换了,安全就万无一失了吧?”
这种想法在实际安全事件中可能是灾难的开始。
>
🎯 本文涵盖内容
- AWS KMS 自动密钥轮换的实际作用和不作用
- 轮换时自动重新加密的服务 vs 需要手动操作的服务对比
- 安全事件(Security Incident)发生时,“密钥更换”与轮换有何不同
- 安全事件响应时各服务密钥更换流程实战整理
📌 引言 — “开启轮换就安全了”的误解
AWS 安全指南中总会提到一句话:“启用 KMS CMK 自动轮换。” 许多人认为这一个设置就能完成密钥安全,但实际上,这只说对了一半。
即使开启了密钥轮换,大多数服务都不会自动将已加密数据更换为新密钥。更重要的是,在实际发生安全事件,需要完全更换密钥的情况下,仅靠轮换是解决不了任何问题的。因为这需要完全不同的流程。
接下来,我们将明确地整理这两点。

🔍 什么是 AWS KMS 密钥轮换? — 究竟发生了什么
轮换的实质:密钥ID不变,内部材料更换
在 KMS 中启用自动密钥轮换(Automatic Key Rotation)后,每年(或按设定的周期)都会生成新的后端密钥材料(Backing Key Material)。重要的是以下几点:
- ✅ KMS Key ID / ARN 不变 → 无需更改现有应用程序设置
- ✅ 旧密钥材料仍保留在 KMS 内部 → 过去加密的数据仍可解密
- ✅ 新加密的数据将使用新密钥材料加密
- ❌ 不会自动将现有加密数据重新加密为新密钥材料
简单比喻,公寓门牌号(Key ID)不变,只是新做了一把钥匙(Key Material),但现有的锁(加密数据)仍然是用旧钥匙锁着的。不过,KMS 会一直保留旧钥匙的副本,所以门仍然可以打开。
两种轮换方式
자동 로테이션: KMS가 주기적으로 키 소재 자동 생성
→ Customer Managed Key (CMK)에서 설정 가능
→ AWS Managed Key는 자동으로 3년마다 로테이션
수동 로테이션: 사용자가 직접 새 KMS 키를 생성 후 서비스에 연결
→ 침해사고 시 필요한 방식
→ Key ID/ARN이 완전히 바뀜 → 재암호화 필수
📊 自动轮换时各服务的重新加密行为
✅ 轮换时自动重新加密现有数据的服务
| 服务 | 重新加密 | 操作条件 |
|---|---|---|
| AWS Secrets Manager | 更改密钥值的KMS密钥时立即重新加密 | 执行 update-secret –kms-key-id 时 |
| AWS Systems Manager Parameter Store | 更新 SecureString 参数时重新加密 | 再次 put 参数值时 |
| Amazon Redshift | 内置集群加密密钥更换功能 | 使用 rotate-encryption-key API |
这些服务的共同点是,“密钥更换 = 数据重新加密”被设计为一个单一操作。操作员无需单独迁移数据。
❌ 不会自动重新加密的服务 — 需要手动操作
| 服务 | 现有数据状态 | 重新加密方法 |
|---|---|---|
| Amazon S3 | 现有对象保持不变 | s3 cp 或 S3 Batch Operations |
| Amazon EBS | 现有卷/快照保持不变 | 复制快照 + 创建新卷 |
| Amazon RDS / Aurora | 现有DB实例保持不变 | 恢复快照 + 指定新KMS密钥 |
| Amazon DynamoDB | 表的KMS密钥无法更改 | 导出 → 创建新表 → 导入 |
| Amazon EFS | 现有文件系统保持不变 | 创建新EFS + 数据迁移 |
| AWS Lambda 环境变量 | 现有加密值保持不变 | 函数更新时自动重新加密 |
> 💡 S3、EBS、RDS“不重新加密”并不意味着存在安全问题。KMS 会保留旧密钥材料,因此始终可以解密。但这表示旧数据将继续使用旧版本密钥材料进行加密。
⚡ 安全事件中的“密钥更换” — 与轮换完全不同的概念
轮换 vs 密钥更换,有何不同?
| 项目 | 自动轮换 | 安全事件密钥更换 |
|---|---|---|
| Key ID/ARN | 不变 | 生成全新密钥 |
| 现有密钥材料 | 保留在KMS内部 | 废弃对象 (攻击者已知) |
| 目的 | 一般安全卫生 | 阻止暴露密钥的影响 |
| 是否需要重新加密 | 可选 | 强制 |
| 停机时间 | 无 | 可能因服务而异 |
安全事件中需要“密钥更换”的原因很简单。如果攻击者获得了密钥材料(或可以使用密钥的IAM凭证),即使通过轮换生成了新的密钥材料,攻击者仍然可以通过KMS API进行解密。如果旧密钥材料仍在KMS中,且攻击者的权限仍然存在,那么轮换就毫无意义。
真正的密钥更换应按以下顺序进行。
🛠️ 安全事件中的密钥更换流程
步骤 1 — 隔离:立即阻止现有密钥和权限
# 停用现有KMS密钥(立即阻止解密)
aws kms disable-key --key-id <compromised-key-id>
# 立即撤销使用该密钥的IAM角色/用户权限
aws iam detach-role-policy --role-name <role> --policy-arn <policy-arn>
# 使用CloudTrail检查最近的密钥使用记录
aws cloudtrail lookup-events
--lookup-attributes AttributeKey=ResourceName,AttributeValue=<key-id>
⚠️ 停用密钥将立即导致现有加密数据无法解密。请务必先制定重新加密计划再进行。
步骤 2 — 创建新的 KMS 密钥
# 创建新的客户管理密钥
aws kms create-key
--description "replacement-key-after-incident"
--key-usage ENCRYPT_DECRYPT
--key-spec SYMMETRIC_DEFAULT
# 设置别名
aws kms create-alias
--alias-name alias/new-data-key
--target-key-id <new-key-id>
# 启用自动轮换
aws kms enable-key-rotation --key-id <new-key-id>
步骤 3 — 各服务重新加密
S3 — 利用 S3 Batch Operations
# 方法1:复制单个存储桶对象(SSE-KMS密钥更换)
aws s3 cp s3://my-bucket/ s3://my-bucket/
--recursive
--sse aws:kms
--sse-kms-key-id <new-key-id>
--metadata-directive REPLACE
# 方法2:对于大规模操作,建议创建S3 Batch Operations Job
# (清单 → 复制操作 → 指定新的KMS密钥)
EBS — 快照复制方式
# 1. 创建现有卷的快照
aws ec2 create-snapshot
--volume-id vol-xxxxxxxx
--description "pre-key-rotation-snapshot"
# 2. 使用新的KMS密钥复制快照(重新加密)
aws ec2 copy-snapshot
--source-region ap-northeast-2
--source-snapshot-id snap-xxxxxxxx
--encrypted
--kms-key-id <new-key-id>
--description "reencrypted-snapshot"
# 3. 从新快照创建卷 → 替换现有卷
aws ec2 create-volume
--snapshot-id <new-snap-id>
--availability-zone ap-northeast-2a
--volume-type gp3
RDS — 快照恢复方式
# 1. 创建手动快照
aws rds create-db-snapshot
--db-instance-identifier mydb
--db-snapshot-identifier mydb-snapshot-for-rekey
# 2. 复制快照(使用新的KMS密钥重新加密)
aws rds copy-db-snapshot
--source-db-snapshot-identifier mydb-snapshot-for-rekey
--target-db-snapshot-identifier mydb-snapshot-reencrypted
--kms-key-id <new-key-id>
# 3. 从新快照恢复DB实例
aws rds restore-db-instance-from-db-snapshot
--db-instance-identifier mydb-new
--db-snapshot-identifier mydb-snapshot-reencrypted
Secrets Manager — 最简单
# KMS密钥更换 + 立即重新加密(单个命令)
aws secretsmanager update-secret
--secret-id my-secret
--kms-key-id <new-key-id>
DynamoDB — 最复杂,会产生停机时间
# 1. 现有表的Point-in-Time Recovery或导出到S3
aws dynamodb export-table-to-point-in-time
--table-arn arn:aws:dynamodb:...:table/MyTable
--s3-bucket my-export-bucket
# 2. 使用新的KMS密钥创建新表
aws dynamodb create-table
--table-name MyTable-New
--sse-specification Enabled=true,SSEType=KMS,KMSMasterKeyId=<new-key-id>
# ... 其他表设置
# 3. 从S3导入数据
aws dynamodb import-table
--s3-bucket-source S3Bucket=my-export-bucket,S3KeyPrefix=...
--input-format DYNAMODB_JSON
--table-creation-parameters ...
⚠️ 注意事项 / 常见错误
🚨 错误 1 — 过早删除旧密钥
침해사고라고 해서 기존 키를 즉시 삭제하면
재암호화 전 데이터가 영구 손실됩니다.
올바른 순서: 비활성화 → 재암호화 완료 → 삭제 예약(최소 7일)
🚨 错误 2 — 误以为仅靠轮换就完成了安全事件响应
如果攻击者窃取了具有 kms:Decrypt 权限的 IAM 凭证,密钥轮换毫无意义。撤销 IAM 权限 + 创建新密钥 + 重新加密才是完整的应对措施。
🚨 错误 3 — 所有服务重新加密后,旧密钥状态被忽视
# 确认重新加密完成后,务必安排删除
aws kms schedule-key-deletion
--key-id <old-key-id>
--pending-window-in-days 30
🚨 错误 4 — 低估 DynamoDB 密钥更换的复杂性
DynamoDB 没有直接更改现有表 KMS 密钥的 API。导出 → 重新创建 → 导入的过程中可能会出现停机时间或数据一致性问题,因此务必建立变更管理流程。
✅ 总结 / 结束语
AWS KMS 密钥管理的核心可以总结为一句话:
轮换保护未来,密钥更换保护现在。
| 情况 | 正确应对 |
|---|---|
| 一般安全卫生 | 启用自动轮换 |
| 凭证暴露嫌疑 | 立即停用 + 创建新密钥 + 重新加密 |
| 自动重新加密支持 | Secrets Manager, Parameter Store, Redshift |
| 需要手动重新加密 | S3, EBS, RDS, DynamoDB, EFS |
下一步,您可以结合配置 AWS Config Rule 自动检测未配置 CMK 轮换,以及 CloudTrail + EventBridge 构建密钥使用异常警报,从而完善基于 KMS 的安全体系。

发表回复