密钥生命周期管理:创建、轮换、删除的最佳实践
密钥生命周期管理,说白了就是管好一个密钥从生到死的全过程。我刚开始接手云上密钥时,总觉得只要把密钥创建出来、配好权限就完事了。直到有一次合规审计,对方问我要过去三年的轮换记录,我才发现自己几乎没做过自动轮换……那次之后我彻底改了。
密钥跟人一样,有出生、有中年、有退役。每个阶段都有坑,今天我把这些年踩过的坑和总结出来的最佳实践,一条条掰开讲。
1. 密钥创建:别让第一步就埋雷
创建密钥看着简单,但我在项目里见过太多“一键生成”后直接给生产环境用的例子。问题都不小。
- 策略先行:创建前先定义好谁可以管理、谁可以使用。AWS 里就是 Key Policy + IAM 策略的组合,Azure 里是 Key Vault 的访问策略和 RBAC。我个人习惯用最小权限原则,从第一天就把管理者和使用者分开。
- 材料来源:除非有特殊合规要求(比如 FIPS 140-2 Level 3),否则我强烈建议用云服务的硬件安全模块(HSM)生成密钥材料。AWS 用 CloudHSM 或默认的 KMS HSM,Azure 用 Managed HSM。软件生成的材料,你想想看,真的能保证随机数质量吗?
- 密钥唯一性:每个环境(开发、测试、生产)用独立的密钥,不要复用。我记得有个客户把开发环境的 CMK 直接给了生产,结果开发人员误删了密钥,整个线上业务加密链路都断了……
- 标签与元数据:创建时带上足够多的标签(用途、创建人、到期日),后续审计时你会感谢自己的。
2. 密钥轮换:频率比想象中更重要
轮换是把旧密钥“退役”并启用新密钥的过程。核心问题就两个:多久轮一次?谁来做?
先看轮换频率。我见过一个银行客户,合规要求每90天轮换一次,但他们手动记录,经常超期。后来我帮他们改成自动化轮换,每季度自动生成新密钥版本,旧版本继续用于解密旧数据。AWS 和 Azure 的轮换机制差别不小,我整理了一张表:
| 维度 | AWS KMS | Azure Key Vault |
|---|---|---|
| 自动轮换 | 自动轮换(可选,每3年一次固定周期) | 无内置自动轮换,需自定义实现 |
| 手动轮换 | 创建新密钥并启用,旧密钥保留为先前版本 | 创建新密钥版本,手动更新使用方引用 |
| 密钥版本管理 | 自动管理版本,key ID 不变 | 密钥名称不变,版本号变化,需代码处理 |
| 轮换事件通知 | CloudTrail 日志记录 | 可通过 Event Grid 触发通知 |
你可能会问:轮换这么频繁,旧数据怎么解密?其实密钥轮换不是销毁旧密钥,而是让旧密钥进入只解密不解密状态。AWS 会自动使用新版本加密新数据,Azure 需要你在应用层处理好版本引用。
对于高合规场景(比如 PCI DSS),我建议至少每 12 个月轮换一次加密密钥,每 3 年轮换一次主密钥。AWS 的自动轮换虽然方便,但它的固定周期是 3 年,如果你需要更短周期,就得手动或用 Lambda 实现。
3. 密钥删除与退役:软删除是你的安
删除密钥是生命周期中最危险也最容易被忽视的一步。我一再跟团队强调:不要直接硬删除生产密钥。
AWS 和 Azure 都提供了“软删除”机制。在 AWS 里,删除 CMK 必须指定一个等待期(7-30 天),期间密钥处于 Pending Deletion 状态,可以取消删除。Azure Key Vault 的软删除默认保留 90 天,删除后密钥进入 Disabled + Soft-Deleted 状态,可以恢复。
- 为什么需要软删除? 因为密钥删除后,所有用它加密的数据就永远无法解密了。我曾见过一个运维人员误删了数据库的加密密钥,幸好软删除还在,我们花了 30 分钟恢复,否则就是灾难。
- 什么时候真正硬删除? 只有当你确定所有加密数据都已经迁移或过期,且合规允许后,才做硬删除。硬删除后无法恢复,所以务必先做审计记录。
- 审计与记录:无论软删除还是硬删除,都要记录操作人、时间、密钥 ID 和原因。AWS 的 CloudTrail 和 Azure 的 Monitor 日志都非常详细。
deletion_window_in_days = 30(AWS)或 soft_delete_retention_days = 90(Azure)。同时写一个自动化的“预删除检查”脚本,扫描所有引用该密钥的 CloudWatch 或 Azure Monitor 告警。如果还有引用,直接拒绝删除。
4. 生命周期一体化的 SVG 流程
下面这张图把创建、轮换、删除的完整流程串起来了。你可以看到每个阶段的关键活动和退出条件。
5. 跨云生命周期自动化:用代码管理密钥
手动管理密钥生命周期,在两百个密钥以下还能凑合;一旦上了规模,必须上自动化。我自己同时管理 AWS 和 Azure 的密钥库,主要靠 Terraform 和 Python 脚本。
以下是一个同时适用于两个云的典型 Terraform 代码片段(简化的示例):
# AWS KMS 密钥创建 + 自动轮换
resource "aws_kms_key" "my_key" {
description = "生产环境加密密钥"
deletion_window_in_days = 30
enable_key_rotation = true # 开启自动轮换
policy = data.aws_iam_policy_document.kms_policy.json
tags = {
Environment = "production"
ManagedBy = "Terraform"
}
}
# Azure Key Vault 密钥创建(需要自定义轮换逻辑)
resource "azurerm_key_vault_key" "my_key" {
name = "my-production-key"
key_vault_id = azurerm_key_vault.prod.id
key_type = "RSA"
key_size = 2048
key_opts = ["encrypt", "decrypt", "sign", "verify"]
tags = {
Environment = "production"
}
}
轮换的自动化我更喜欢用云函数定时触发。AWS 上写一个 Lambda,读取所有 CMK 的创建时间,超过 90 天的就创建一个新密钥版本。Azure 上可以用 Azure Functions 配合 Event Grid 轮询。代码其实不复杂,但千万注意:轮换后要通知下游服务刷新密钥引用。
最后说一句真心话:密钥生命周期不是一个“配一次就完”的事情。合规在变、业务在变,你必须在每个阶段都留有审计痕迹和回退能力。如果你能把这套流程做成代码化的 pipeline,那以后不管上什么云,心里都有底。