使用mybatis拦截器实现业务层和持久化层的数据处理、加密、解密、脱敏。

本文介绍了一种使用MyBatis拦截器实现字段级别的加密、解密及脱敏处理的方法,并提供了一个开源的Spring Boot Starter,支持AES和MD5算法,允许自定义加密解密器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接上篇
上次说实现隐私字段数据库存储加密想到两种方式,

  1. 一个是使用数据库的触发器,但是这种在查询的时候没有触发器,所以想在查询的时候反向解密,又要大量改代码,就麻烦了,加上隐私字段需要脱敏处理返回给前端所以采用第二种方法。
  2. 使用mybatis拦截器实现业务层和持久化层的数据处理、加密、解密、脱敏。(就像pagehelper分页插件实现路数一样),刚好有个公众号推了一篇文章苞米豆开发了商业项目mybatis-mate-starter,问了下需要收费(2021-11-18)个人版 99 ,企业版 499 ,虽然不贵但是我这边项目只需要加解密和脱敏处理正好练一下手就自己写了。

实现逻辑:

  1. 定义个注解作用域为类的属性上,用于标识这个属性需要加密或解密。
  2. 实现mybatis拦截器添加加解密逻辑。
  3. 加解密逻辑:判断如果是新增和更新操作拿到该注解属性的原值进行加密,如果是查询操作就拿到数据库值反向解密。

实现代码:

https://gitee.com/china-zhz/privacy-spring-boot-starter.git
这是spring-boot-starter项目,我已经创建了发行版,也可以直接引用该依赖使用:

        <dependency>
            <groupId>com.gitee.china-zhz</groupId>
            <artifactId>privacy-spring-boot-starter</artifactId>
            <version>1.0.0.RELEASE</version>
        </dependency>

依赖下载失败可以添加依赖仓库到项目中:

    <repositories>
        <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>
    </repositories>

使用方式:

  1. 引入依赖后把注解放到要加的类属性上如:
@Data
@TableName("user")
@ApiModel(value = "UserPo对象", description = "本系统用户表")
public class UserPo implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "主键")
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;

    @ApiModelProperty(value = "用户姓名")
    private String userName;

    @ApiModelProperty(value = "密码")
    @FieldEncrypt
    private String password;

    @ApiModelProperty(value = "手机号")
    private String phone;

    @ApiModelProperty(value = "邮箱")
    private String email;

    @ApiModelProperty(value = "创建时间")
    private LocalDateTime createDate;

    @ApiModelProperty(value = "更新时间")
    private LocalDateTime updateDate;


}

  1. 然后调用接口就可以了

效果:

插入更新效果图
在这里插入图片描述
查询效果图:
在这里插入图片描述

备注:

① @FieldEncrypt 注解默认使用AES算法,现在是集成了两种算法MD5和AES ,MD5是不可逆算法不可以解密,AES可以反向解密,默认的AES加密解密时我固定了一个秘钥,如果想自定义秘钥有两种方式:

  1. 全局配置yml文件里
privacy:
  crypto:
    key: jshfdiwhfkjncwolmas

  1. .加注解上
    @ApiModelProperty(value = "密码")
    @FieldEncrypt(key = "qwertyuiop")
    private String password;

注解秘钥优先级高于全局秘钥
② 如果你想使用MD5加密

    @ApiModelProperty(value = "密码")
    @FieldEncrypt(algorithm = Algorithm.MD5)
    private String password;

③ 如果这两个都不想用可以自定义加密解密器只需要实现ICrypto接口自定义加密解密方法,在注解属性里指定该类即可

@Slf4j
public class MyCrypto implements ICrypto {

    @Override
    public String encrypt(Algorithm algorithm, String s, String s1) throws Exception {
        log.debug("---------------------------"+s+s1);
        return "zxcvbnm";
    }

    @Override
    public String decrypt(Algorithm algorithm, String s, String s1) throws Exception {
        log.debug("---------------------------"+s+s1);
        return "mnbvcxz";
    }
}

脱敏处理功能已添加,注解为@FieldDesensitize,使用方式和加密一样简单自动识别手机号码、邮箱、银行卡号、身份证号码,可以自定义填充值,默认是星号,可以自定义脱敏器。

@Data
@EqualsAndHashCode(callSuper = false)
@TableName("user")
@ApiModel(value="UserPo对象", description="本系统用户表")
public class UserPo implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "主键")
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;

    @ApiModelProperty(value = "用户姓名")
    private String userName;

    @ApiModelProperty(value = "密码")
    private String password;

    @ApiModelProperty(value = "手机号")
    private String phone;
    
    @FieldDesensitize(fillValue = "#")
    @ApiModelProperty(value = "邮箱")
    private String email;

    @ApiModelProperty(value = "创建时间")
    private LocalDateTime createDate;

    @ApiModelProperty(value = "更新时间")
    private LocalDateTime updateDate;


}

项目问题欢迎讨论指正,也可以贡献自己的代码到仓库。

评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

china-zhz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值