# mall-sensitive **Repository Path**: waming5/mall-sensitive ## Basic Information - **Project Name**: mall-sensitive - **Description**: 本工具是基于mybatis的插件机制、spring boot jackson json序列化编写的一套加密和脱敏的工具。 使用时通过注解属性加密,存储数据库时会自动加密存储。 查询时会自动解密出明文。 api接口层,通过注解指定属性需要脱敏,spring boot在输出JSON格式数据时属性脱敏输出。 内置了一些常用数据的脱敏处理方式 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2023-10-31 - **Last Updated**: 2025-12-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # mybatis插件数据加解密,spring boot接口输出json格式数据脱敏 ## 介绍 本工具是基于mybatis的插件机制、spring boot jackson json序列化编写的一套加密和脱敏的工具。
使用时通过注解属性加密,存储数据库时会自动加密存储。 查询时会自动解密出明文。
api接口层,通过注解指定属性需要脱敏,spring boot在输出JSON格式数据时属性脱敏输出。 内置了一些常用数据的脱敏处理方式。
## 设计目标 #### 对应用和使用者透明,业务逻辑无感知,通过配置集成,改动代码量小。 #### 加密算法可扩展。 ## 实现原理 1,拦截mybatis的StatementHandler 针对读写请求进行字段的加密。
2,拦截mybatis的ResultSetHandler,针对读请求的响应进行加密字段的解密赋值。
## 使用方式 0,导入依赖 ```xml com.hose.mall mall-sensitive-plugin 1.0.0-SNAPSHOT ``` 1,编写加解密实现类以及配置mybatis的插件,下面在springboot场景下的一个配置案例。 ```java /** * 插件配置 */ @Configuration public class EncryptPluginConfig { //加密方式 @Bean Encrypt encryptor() throws Exception{ return new AesSupport("1870577f29b17d6787782f35998c4a79"); } //配置插件 @Bean ConfigurationCustomizer configurationCustomizer() throws Exception{ DecryptInterceptor decryptReadInterceptor = new DecryptInterceptor(encryptor()); EncryptWriteInterceptor encryptWriteInterceptor = new EncryptWriteInterceptor(encryptor()); return (configuration) -> { configuration.addInterceptor(decryptReadInterceptor); configuration.addInterceptor(encryptWriteInterceptor); }; } } ``` 2,在vo类上添加功能注解使得插件生效: ```java @EncryptEnabled public class UserDTO { private Integer id; /** * 用户名 */ @EncryptField private String userName; /** * 脱敏的用户名 */ @SensitiveField(SensitiveType.CHINESE_NAME) private String userNameSensitive; /** * 属性赋值别名绑定,从userName字段获得并进行脱敏 */ @SensitiveBinded(bindField = "userName",value = SensitiveType.CHINESE_NAME) private String userNameOnlyDTO; /** * 身份证号 */ @EncryptField private String idcard; /** * 脱敏的身份证号 */ @SensitiveField(SensitiveType.ID_CARD) private String idcardSensitive; private int age; @SensitiveField(SensitiveType.EMAIL) private String email; } ``` ## 注解详解 #### @EncryptEnabled 标记Class类上,声明此数据库映射的model对象开启数据加密功能。 #### @EncryptField 标记属性字段上,必须是字符串,声明此字段在和数据库交互前将数据加密。 update,select,insert 都会将指定的字段设置为密文与数据库进行交互。 在select的结果集里,此字段会自动解密成明文。业务是无感知的。 #### @SensitiveField(SensitiveType.CHINESE_NAME) 标记在字段上,必须是字符串。 声明此属性在spring boot输出JSON,会脱敏输出。 SensitiveType是脱敏类型,详见脱敏类型章节。 一般考虑如下场景。 //数据库加密存储 @EncryptField private String phone; //spring boot JSON输出脱敏格式 @SensitiveField(SensitiveType.MOBILE_PHONE) private String phoneSensitive; #### @SensitiveBinded(bindField = "userName",value = SensitiveType.CHINESE_NAME) 此注解适用于如下场景: 例如,数据库只存了username字段的加密信息,没有冗余脱敏展示的字段。 响应类里希望将数据库的加密的某个字段映射到响应的两个属性上(一个解密的属性,一个脱敏的属性)就可以使用该注解。 例如,dto里有如下字段: @EncryptField private String username @SensitiveBinded(bindField = "userName",value = SensitiveType.CHINESE_NAME) private String userNameOnlyDTO; 则当查询出结果时,userNameOnlyDTO会赋值为username解密后再脱敏的值。 相当于数据库的一个字段的值以不同的形式映射到了对象的两个字段上。 ## 脱敏类型 ```java public enum SensitiveType { /** * 不脱敏 */ NONE, /** * 默认脱敏方式 */ DEFAUL, /** * 中文名 */ CHINESE_NAME, /** * 身份证号 */ ID_CARD, /** * 座机号 */ FIXED_PHONE, /** * 手机号 */ MOBILE_PHONE, /** * 地址 */ ADDRESS, /** * 电子邮件 */ EMAIL, /** * 银行卡 */ BANK_CARD, /** * 公司开户银行联号 */ CNAPS_CODE, /** * 支付签约协议号 */ PAY_SIGN_NO } ``` ## 注意事项 #### 测试用例 在mall-sensitive-web包下有完整的测试用例。 #### 使用领域对象化的参数和响应 必须使用javabean类入参声明方式才能使得本插件生效。例如: ```java int insert(UserDTO userDTO); ``` 使用如下的方式操作mybatis,则本插件无效。 ```java int insert(Map map); int insert(String username,String idcard); ``` #### sql应该是预编译类型的 sql语句应该使用如#{userName}这种预编译的方式组织变量,不能使用'${userName}'这种方式。