🔐 AWS KMS 密钥轮换,您真的了解并正确使用了吗?— 自动重新加密服务全面总结 + 安全事件中密钥更换的实战指南

“密钥轮换了,安全就万无一失了吧?”

这种想法在实际安全事件中可能是灾难的开始。

>


🎯 本文涵盖内容

  • 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 的安全体系。



Comments

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注