敏感数据怎么防拖库?信封加密(DEK+KEK 二层密钥)架构设计与 Java 实战

一个密钥加密所有数据,够吗

最简单的加密:用一把主密钥 KEK 直接加密所有业务数据。问题也很直接------这把密钥一旦泄露,全军覆没;而且每次加解密都要调用 HSM,高并发下性能扛不住。

更合理的做法,是像寄信一样:把信(数据)装进信封,用信封钥匙(DEK)锁上;信封钥匙本身再装进一个铁箱,用铁箱钥匙(KEK,由 HSM 保管)锁上。这就是信封加密(Envelope Encryption)

二层密钥体系:DEK + KEK

复制代码
业务数据  ──DEK加密──▶  密文数据
DEK      ──KEK加密──▶  密文DEK(和数据一起存)
KEK      ──HSM保管──▶  永不明文导出
  • DEK(数据密钥):只用来加密业务数据本身,可以每条数据一把,用完即弃或定期轮换;
  • KEK(主密钥) :由 KSP / HSM 管理,只用来加密 DEK,自身永不明文导出硬件
  • 存储时,密文数据 + 密文 DEK 一起落库。

攻击者即使拖走整库,拿到的也只是"密文数据 + 被 KEK 锁住的密文 DEK"------没有 HSM 里的 KEK,解不开任何东西。

为什么它比单密钥更稳

  1. 缩小爆炸半径:DEK 泄露只影响部分数据,KEK 始终在 HSM 内;
  2. 性能更好:高频的数据加解密用 DEK(软件/本地即可),只有偶尔的 DEK 加解密才碰 HSM;
  3. 轮换灵活:换 DEK 不用重新加密全量数据,换 KEK 不影响历史密文结构;
  4. 合规清晰:密钥分层对应"数据密钥 / 主密钥"的密评要求。

Java 调用 KSP 实战

KSP 提供 Java SDK 与 RESTful API。下面用 RESTful 风格演示"加密一个字段"的闭环(伪代码,密钥名与端点以实际产品为准):

java 复制代码
// 1. 向 KSP 申请一把数据密钥 DEK(明文仅在本次调用返回,建议立即用掉)
HttpClient client = HttpClient.newHttpClient();
String createDek = """
    { "action":"key/create", "type":"SYMMETRIC",
      "alg":"SM4", "length":128, "exportable":true }
    """;
HttpResponse<String> r1 = client.send(
    post("https://ksp-host/api/v1/key", createDek),
    BodyHandlers.ofString());
// r1 返回 { dataKey: "<base64 明文DEK>", keyId: "dek-xxxx" }

// 2. 用 DEK 加密业务字段(本地 SM4)
byte[] dek = Base64.getDecoder().decode(r1.dataKey);
byte[] cipher = Sm4Util.cbcEncrypt(dek, "13800001234".getBytes(StandardCharsets.UTF_8));

// 3. 把 DEK 交给 KSP 用 KEK 加密后归档,本地只留密文 DEK
String wrap = """
    { "action":"key/wrap", "keyId":"dek-xxxx" }
    """;
HttpResponse<String> r2 = client.send(
    post("https://ksp-host/api/v1/key/wrap", wrap),
    BodyHandlers.ofString());
// r2 返回 { wrappedDek: "<被KEK加密的密文DEK>" }

// 4. 落库:密文数据 + 密文DEK + keyId
jdbc.update("INSERT INTO user(phone_cipher, dek_wrapped, dek_id) VALUES(?,?,?)",
    Base64.getEncoder().encodeToString(cipher), r2.wrappedDek, "dek-xxxx");

解密时反向:用 keyId 向 KSP 申请 unwrap 拿回 DEK,再用 DEK 解 phone_cipher。整个过程业务明文密钥从不落库,KEK 从不离开 HSM

字段级加密的典型场景

  • 身份证号、手机号、银行卡号等 PII 字段;
  • 电力营销系统敏感字段端到端加密(KSP + SM2 UKey,浏览器端加密,服务端不落地明文);
  • 汽车研发 PLM 三维模型文件"谁上传、谁能解密"的细粒度授权。

小结

信封加密把"一把钥匙守所有数据"变成"每封信有自己的钥匙,所有钥匙锁进 HSM 铁箱"。它既扛得住拖库,又扛得住高并发,还是密评里"密钥分层管理"的标准答法。

下一篇换个威胁模型:不是拖库,而是勒索病毒把文件全加密了------KSP 的 RDM 怎么拦。

相关推荐
我是唐青枫1 小时前
Java JCommander 实战详解:用注解解析命令行参数
java·开发语言
大鹏说大话1 小时前
C++ 内存布局详解:类、虚函数、虚表底层原理
java·开发语言
键盘会跳舞2 小时前
C++:容器适配器 queue 的源码级拆解
开发语言·c++·queue
还是鼠鼠2 小时前
Spring AI连接DeepSeek与通义千问:application.yaml配置详解
java·通义千问·spring ai·deepseek
QAQo7T2 小时前
Python组蓝桥杯备赛超详细知识点总结笔记_排序算法篇
笔记·python·算法·蓝桥杯·排序算法
醉颜凉3 小时前
蓝桥杯2025年第十六届省赛真题-最大数字 Python题解
python·职场和发展·蓝桥杯
计算机小白一个3 小时前
蓝桥杯 Java B 组之哈希表应用(两数之和、重复元素判断)
java·数据结构·算法·蓝桥杯
Loge编程生活3 小时前
打卡信奥刷题(3449)用C++实现信奥题 P10429 [蓝桥杯 2024 省 B] 拔河
开发语言·数据结构·c++·算法·青少年编程
卷无止境3 小时前
当独立开发者也能造出3A画质的游戏:Godot引擎深度解析
后端·python·godot