信封加密是怎么跑的
云上处理大批数据时不会让 KMS 直接加密业务数据——KMS 的强项是保护密钥而不是吞吐数据。通行做法是信封加密:调用 KMS 的数据密钥接口,一次拿到两份东西,明文数据密钥与用主密钥加密后的数据密钥密文;本地用明文密钥加密数据,随即从内存中丢弃明文,只保留数据密文、密文密钥与密钥版本标识。解密时反过来:先让 KMS 解出数据密钥,再用它解数据。这样主密钥始终待在 KMS 里,数据量再大也不受 KMS 吞吐限制。
基本信息
| 关键接口 | GenerateDataKey 一类接口,返回明文数据密钥与密文数据密钥 |
|---|---|
| 存储内容 | 数据密文 + 密文数据密钥 + 密钥版本标识 |
| 解密流程 | KMS 解密数据密钥 -> 本地解密数据 -> 立即丢弃明文密钥 |
| 密钥轮换 | 轮换主密钥不影响既有密文,密文里保留版本信息即可 |
| 调用配额 | KMS 有请求配额与延迟,高并发场景需要缓存或批量策略 |
| 审计 | 每次 KMS 调用都会留痕,可作为密钥使用监控的数据源 |
典型使用场景
- 对象存储加密:大量小文件用统一数据密钥,按对象或按批次控制粒度。
- 数据库字段加密:敏感字段单独加密,主密钥放 KMS 便于集中管控。
- 备份归档:归档文件加密后长期保存,密钥版本随归档一起记录。
- 多租户隔离:按租户派生不同数据密钥,降低跨租户影响。
- 合规改造:把散落的应用内置密钥替换为 KMS 托管。
信封加密流程
信封加密流程
GenerateDataKey -> (plaintext DEK, encrypted DEK)
encrypt(data, plaintext DEK) -> data_ciphertext
store(data_ciphertext, encrypted DEK, key_version)
wipe plaintext DEK from memory as soon as possible
# 解密侧
KMS Decrypt(encrypted DEK) -> plaintext DEK -> decrypt(data_ciphertext)
# 轮换主密钥后,旧密文仍可通过其携带的密钥版本正常解密步骤与注意点
| 步骤 | 输入输出 | 注意 |
|---|---|---|
| 申请数据密钥 | 得到明文与密文两份 | 明文只在内存中短暂存在 |
| 加密数据 | 数据 + 明文密钥 -> 密文 | 选择带认证的加密模式 |
| 落盘保存 | 数据密文 + 密文密钥 + 版本 | 三者必须成组保存与迁移 |
| 解密数据 | 密文密钥 + 数据密文 | 先解密钥再解数据,顺序不可颠倒 |
| 轮换主密钥 | 新版本主密钥 | 密文无需重写,靠版本标识兼容 |
明文数据密钥绝不能写入磁盘、日志或错误上报中;同时评估 KMS 调用配额,避免高并发场景因限流导致批量解密失败。