第3章 密钥层次结构:根密钥、KEK、DEK
为什么需要分层?
直接拿一把密钥加密所有数据,听起来省事。但你想想看,一旦这把密钥泄露,全部数据都得报废。我在一个金融项目里遇到过这种事——运维误把密钥上传到公开代码仓库,当天就得打补丁换掉十几T的数据。
分层设计说白了就是把鸡蛋放在不同篮子里。高层密钥少用、严管;底层密钥多换、快换。这样即使底层泄露,损失也能控制在小范围内。
根密钥(Master Key)
根密钥是整个体系的“核按钮”。它只用来加密和防护下一层的KEK,绝不直接碰业务数据。我个人习惯把根密钥放在硬件安全模块(HSM)里,或者用密钥管理服务(KMS)保管。它的安全假设是:
- 物理隔离——能从硬件层面阻止非授权读取
- 极少使用——一年可能只用几次,比如轮换KEK的时候
- 备份强控——我曾经见过一个团队把根密钥打印成纸质放保险柜,结果保险柜钥匙丢了……嗯,后来他们改用shamir秘密共享了
密钥加密密钥(KEK)
KEK是中间层,专用于保护数据加密密钥(DEK)。你可以把它理解成“管家”——根密钥锁在保险柜里,KEK保管保险柜的权限。实际使用中,KEK会以密文形式存储在数据库或配置文件里,只有应用启动时才由根密钥解密加载。
这里有个坑要注意:KEK本身也需要定期轮换。我曾经做过一次审计,发现客户同一个KEK用了三年没换……他们觉得“反正有根密钥保护就很安全”。其实不对,KEK如果长期不变,被爆破或侧信道攻击的风险会累积。建议每12-18个月换一次。
数据加密密钥(DEK)
DEK是最底层的“打工仔”,直接加密用户数据、文件、数据库字段。它的特点就是数量多、变化快——每个数据对象都可以有自己的DEK,而且能随时生成新的替换旧的。
安全假设就比较松了:即使DEK泄露,也只会影响它所保护的少量数据。我记得有一个云存储项目,他们给每个用户上传的文件都单独生成一个DEK,用该用户的专属KEK加密存储。这样一旦某个DEK丢失,影响的只是那一个文件。
三层的安全假设对比
| 层次 | 存储位置 | 使用频率 | 保护措施 | 轮换策略 |
|---|---|---|---|---|
| 根密钥 | HSM / KMS / 物理隔离 | 极低(月/年) | 硬件保护、多人授权 | 按需(灾难场景) |
| KEK | 密文存储(由根密钥加密) | 低(应用启动、轮换时) | 对称加密 + 访问控制 | 12-18个月 |
| DEK | 密文存储(由KEK加密) | 高(每次读写数据) | 随机生成、按需销毁 | 每次操作或定期 |
实战中的密钥生命周期管理
分层结构不只是在纸上画得好看就行。我在设计一个微服务密钥体系时,把根密钥放在KMS,KEK以加密文件方式挂载到容器,DEK则封装在加密SDK里动态生成。流程大概是:
- 应用启动 → 从KMS用根密钥解密KEK
- 需要加密数据 → 生成随机DEK,用KEK加密后存储
- 需要解密 → 读取密文DEK,用KEK解密,再用DEK解密数据
- DEK轮换 → 重新生成DEK并重新加密数据
整个过程中,根密钥只在第一步出现一次,之后全部在内存里安全操作。我建议每次使用完KEK后,立刻从内存中抹除。
讲到底,密钥分层不是理论游戏。它决定了你的系统被攻破后,能不能快速止血、把损失降到最小。我建议每个团队在设计之初就画清楚自己的三层结构,并且定期演练密钥轮换和灾备恢复流程。