搞定“等保”数据加密:支持密文模糊查询,这可能是你见过最简单的 Java 改造方案

89 阅读5分钟

一、 每一个开发者的“等保”噩梦

在数据安全合规(如等保、密评)的要求下,手机号、身份证、入账金额等敏感信息必须加密存储

但传统的改造方式简直是“代码火葬场”:

  1. 侵入性强:要在每一个 Mapper 的入参和出参上手动写拦截逻辑或标注注解。
  2. 维护难:只要表结构多了一个加密字段,全项目的 SQL 可能都要跟着动。
  3. 查询难:加密后的密文怎么做模糊查询?这是大部分加密方案的“死穴”。

难道就没有一种方案,指定哪张表哪个字段要加密,就能搞定数据库加解密吗?


二、 认识一下 Field-Encryptor:为“懒人”而生的安全框架

Field-Encryptor 是一款专为 Java 开发者打造的透明数据中间层框架。基于Mybatis拦截器。它的核心原则只有一条:让业务代码完全感知不到加解密的存在。

🚀 核心卖点一:真正的“0 侵入”,一处配置全局生效

你不需要修改任何 Service 层, DAO 层或入参响应的逻辑。只需在实体类上轻轻标注一个注解,剩下的交给框架。

🚀 核心卖点二:黑科技——支持密文模糊查询

这是 Field-Encryptor 区别于其他框架的杀手锏。通过独有的 DB 模式,框架会自动改写 SQL,利用数据库原生的加解密函数进行运算。

  • 输入WHERE phone LIKE '%138%'
  • 执行:框架自动将其转换为数据库函数调用,确保即便在加密状态下,模糊搜索依然精准。

🚀 核心卖点三:超强的环境适配性

  • 不绑定框架:无论你用的是原生 MyBatis 还是 MyBatis-Plus,甚至项目里根本没有实体类,它都能通过自动读取 DataSource 结构信息实现无缝接入。
  • 算法随心换DB 模式(依赖数据库函数)和 POJO 模式(支持 SM4、AES 等 Java 算法)自由切换。
  • 复杂场景支持:完美适配分库分表、大写/小写敏感配置等生产级需求。

三、 方案对比:为什么它更香?

维度传统拦截器方案某大型中间件(SS)Field-Encryptor
上手难度繁琐,需逐个修改 Mapper配置极度复杂,学习成本高极简,标注实体类即可
模糊查询几乎不支持支持但需特定配置,得学原生支持 (DB 模式)
代码侵入高侵入0 侵入,但依赖分片逻辑0 侵入,仅需标注表和字段
包体积较重极重极轻量

四、快速体验一下

  • 引入pom (这里暂时使用3.6.0-alpha版本,最新版本提测阶段,尚未发布)
<dependency>
    <groupId>io.gitee.tired-of-the-water</groupId>
    <artifactId>encryptor-core</artifactId>
    <version>3.6.0-alpha</version>
</dependency>
  • 增加配置
#配置@TableName标注的实体类路径
field.scanEntityPackage[0]=com.sangsang.*.entity
#确定想要使用的模式是哪种,目前支持 db  pojo 两种模式配置,这里推荐db
field.encryptor.patternType=db
#自定义秘钥(这里配置秘钥后,默认的加密算法会使用这个秘钥,也可不配置,有默认秘钥)
field.encryptor.secretKey=TIREDTHEWATER
  • 实体类标注
// 注意:这个类的路径需要写在上面配置的路径下,才能扫描到,不想改原有实体类,自己新建个路径
// 这里的栗子是 表tb_user 的字段phone需要密文存储
@Data
@TableName("tb_user")
public class UserEntity {

    @TableField("phone")
    @FieldEncryptor // 没错,就这一个注解,tb_user表的phone字段全局加解密搞定!
    private String phone;
}
  • 验证

没错,你已经改造完毕了,随便写几个试一下吧。目前兼容了常见的99.99%语法

更多个性化使用,pojo模式,db模式差异,实现原理,详见gitee(传送门在文章末尾)

五、原理

项目启动时,会扫描配置路径下的实体类,将需要加解密的表,字段及其对应算法缓存在内存中

sql执行时,会在拦截器层对sql进行语法解析,知道每个字段属于哪张表,结合缓存信息就可以做出相应的处理

db模式

# 假如我们有如下的sql,其中 phone 字段是密文存储的
select  phone,user_name FROM tb_user WHERE phone = ?

# 经过db模式的处理后,实际执行的sql会变成下面
SELECT 
    数据库解密函数(phone) AS phone,
    user_name 
FROM tb_user 
WHERE phone = 数据库加密函数(?)

pojo模式

# 假如我们有如下的sql,其中 phone 字段是密文存储的
select  phone,user_name FROM tb_user WHERE phone = ?
# mapper如下
UserVo selectOne(String phone);
#经过pojo模式处理后,在mybatis拦截器层,会解析发现入参phone是需要密文存储的
#所以会将入参字符串phone进行加密处理,对查询结果中的phone字段在映射成对象时也会进行解密处理

六、 写在最后

Field-Encryptor 的目标不是做一个大而全的中间件,而是精准解决开发者在数据治理中的每一个“痛点”。

文章是AI写的,但是项目是我维护的,转载请标明出处

目前项目已在 Gitee 开源,欢迎各位大佬来点个 Star 鼓励!如果你在使用中遇到任何等保或合规的刁钻需求,欢迎在评论区或 QQ 群交流,我们一起把它做得更好。