Cloud KMS:授权、轮换与销毁
验证:未记录
- 适用版本
- 未记录
- 验证范围
- 尚未登记验证记录。
管理加密密钥;与保存可读取秘密值的 Secret Manager 分开。
推荐做法#
- 管理密钥与使用密钥加解密分别授权,权限尽量限定到 CryptoKey。
- 直接 Encrypt 用于小数据;大对象采用信封加密或服务原生 CMEK。
- 轮换 primary 后保留仍被旧密文使用的版本;销毁前确认恢复需求。
常用操作#
替换为实际资源;本段不依赖 lab.env。
PROJECT_ID='REPLACE_PROJECT_ID'
LOCATION='REPLACE_LOCATION'
KEYRING='REPLACE_KEYRING'
KEY='REPLACE_KEY'
gcloud kms keys versions list --project="$PROJECT_ID" \
--location="$LOCATION" --keyring="$KEYRING" --key="$KEY"容易踩的坑#
轮换不会自动重加密旧数据;销毁仍被使用的 KeyVersion,可能使数据永久不可读。 先确认旧密文和备份的解密依赖,再安排销毁。
- CMEK 另需对应 service agent 权限与服务支持的 location。
配置说明与完整示例(按需展开)
类似 AWS KMS。KMS 管理加密密钥;Secret Manager 管理可被应用取出的秘密值。CMEK 是让服务使用你管理的密钥,不等于应用直接读到了密钥材料。
前置:环境篇,KMS Admin,以及创建 SA/管理其 impersonation 身份授权的权限。
source lab.env
gcloud services enable cloudkms.googleapis.com
export KMS_SA="lab-kms@$PROJECT_ID.iam.gserviceaccount.com"
export HUMAN_EMAIL=$(gcloud config get-value account)
gcloud iam service-accounts create lab-kms
gcloud iam service-accounts add-iam-policy-binding "$KMS_SA" --member="user:$HUMAN_EMAIL" --role=roles/iam.serviceAccountTokenCreator
gcloud kms keyrings create lab-ring --location="$REGION"
gcloud kms keys create lab-key --keyring=lab-ring --location="$REGION" --purpose=encryption
gcloud kms keys add-iam-policy-binding lab-key --keyring=lab-ring --location="$REGION" --member="serviceAccount:$KMS_SA" --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
printf 'synthetic confidential text\n' > plaintext.txt
gcloud kms encrypt --key=lab-key --keyring=lab-ring --location="$REGION" --plaintext-file=plaintext.txt --ciphertext-file=ciphertext.bin --impersonate-service-account="$KMS_SA"
gcloud kms decrypt --key=lab-key --keyring=lab-ring --location="$REGION" --ciphertext-file=ciphertext.bin --plaintext-file=decrypted.txt --impersonate-service-account="$KMS_SA"
cmp plaintext.txt decrypted.txt验收:文件相同;KMS 管理员角色不自动等于可解密,应用仅在这把 key 上有加解密权。直接 Encrypt 适合小数据;大对象通常采用信封加密或服务原生 CMEK。加解密
轮换与旧密文#
gcloud kms keys versions create --key=lab-key --keyring=lab-ring --location="$REGION" --primary
gcloud kms keys versions list --key=lab-key --keyring=lab-ring --location="$REGION"
gcloud kms decrypt --key=lab-key --keyring=lab-ring --location="$REGION" --ciphertext-file=ciphertext.bin --plaintext-file=decrypted.txt --impersonate-service-account="$KMS_SA"
gcloud kms keys versions disable 1 --key=lab-key --keyring=lab-ring --location="$REGION"
# 预期失败:旧密文使用版本 1
gcloud kms decrypt --key=lab-key --keyring=lab-ring --location="$REGION" --ciphertext-file=ciphertext.bin --plaintext-file=decrypted.txt --impersonate-service-account="$KMS_SA"
gcloud kms keys versions enable 1 --key=lab-key --keyring=lab-ring --location="$REGION"禁用状态传播可能需要约一分钟,等待后重试再判断。轮换 primary 不会重新加密既有数据;旧版本必须保留至数据完成迁移。CMEK 的 service agent 需单独授权,地域也要满足目标服务要求。密钥轮换
清理#
确认只有实验密文使用这些版本,再安排销毁;实际销毁后无法解密。
gcloud kms keys versions destroy 1 --key=lab-key --keyring=lab-ring --location="$REGION"
gcloud kms keys versions destroy 2 --key=lab-key --keyring=lab-ring --location="$REGION"
gcloud kms keys remove-iam-policy-binding lab-key --keyring=lab-ring --location="$REGION" --member="serviceAccount:$KMS_SA" --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
gcloud iam service-accounts delete "$KMS_SA"
rm plaintext.txt ciphertext.bin decrypted.txt以上编号假设只创建了两个版本;先核对 list 输出。本例 destroy 是安排销毁密钥材料,等待期内按规则可取消,实际销毁后不可恢复;它不等于从资源列表删除。
截至 2026-10-15,Cloud KMS 已支持按以下条件删除资源,不能再按“KeyRing 永远不能删除”理解:
| 资源 | 删除条件 |
|---|---|
| KeyVersion | 状态为 DESTROYED、IMPORT_FAILED 或 GENERATION_FAILED;导入的版本仅在导入失败时可删除 |
| CryptoKey | 所有版本已删除、无自动轮换计划,且不是 Autokey 创建 |
| KeyRing | 所有 key 已删除,全部 import job 已过期 |
先处理数据恢复需求,再按版本 → key → key ring 的依赖检查;不要为清空列表而销毁仍需解密的数据。销毁与恢复、资源删除条件