使用Mybatis的TypeHandler实现对数据库敏感字段加解密

背景

近期在做一个对数据安全要求比较高的软件,用户要求做到对接口、文件、以及数据库部分敏感字段进行加密。由于系统数据库中部分字段内容非常较敏感,用户要求需要对这些字段内容进行加密存储。

TypeHandler

MyBatis在设置预处理语句(PreparedStatement)中的参数,或从结果集中取出一个值时, 会选择使用对应的TypeHandler类型处理器,将获取到的值以合适的方式转换成 Java 类型。

实现

@Slf4j
@MappedJdbcTypes(JdbcType.VARCHAR)
@Component
public class EncryptTypeHandler extends BaseTypeHandler<String> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        // 在这里进行加密
        String encryptedData = encrypt(parameter);
        ps.setString(i, encryptedData);
    }

    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        // 在这里进行解密
        String encryptedData = rs.getString(columnName);
        if(IrStringUtil.isBlank(encryptedData)){
            return encryptedData;
        }
        return decrypt(encryptedData);
    }

    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        // 在这里进行解密
        String encryptedData = rs.getString(columnIndex);
        return decrypt(encryptedData);
    }

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        // 在这里进行解密
        String encryptedData = cs.getString(columnIndex);
        if(IrStringUtil.isBlank(encryptedData)){
            return encryptedData;
        }
        return decrypt(encryptedData);
    }

    // 加密方法
    private String encrypt(String data) {
        String encryptData = "";
        // 实现你的加密逻辑
        try{
            encryptData = AesEncryptUtils.aesEncrypt(data);
            encryptData = GoConstant.ENCRYPT_TYPE.AES+encryptData;
            return encryptData;
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return data;
    }

    // 解密方法
    private String decrypt(String encryptedData) {
        String decryptData = "";
        // 实现你的解密逻辑
        if(encryptedData.startsWith(GoConstant.ENCRYPT_TYPE.AES)){
            try{
                decryptData = AesEncryptUtils.aesDecrypt(encryptedData.substring(4));
                return decryptData;
            }catch (Exception e){
                e.printStackTrace();
                log.error(e.getMessage());
            }
        }
        return encryptedData;
    }

}

使用

在要加密字段上添加注解@TableField, 配置对应的typeHandler,示例如下:

@TableField(jdbcType = JdbcType.VARCHAR,typeHandler = EncryptTypeHandler.class)
private String phone;

配置好之后使用Mybatis的BaseMapperr内部的新增与修改方法时对应字段会进行加密后再存入数据库,查询时为解密之后的结果。

如果不是Mybatis-Plus的 BaseMapper内部的方法,需要我们在mapper.xml文件中resultMap或者在参数使用时显示的声明TypeHandler,如下:

<!-- 查询解密 -->
<result column="phone" property="phone" typeHandler="com.xxx.xxx.encrypt.handler.EncryptTypeHandler"/>

<!-- 修改加密 -->
<update id="updatePhone">
    update user
    set phone = #{phone, typeHandler=com.example.typeHandle.ClientPhoneTypeHandler}
    where id = #{id}
</update>

总结

1.TypeHandler不仅能做数据库字段加解密,还能做时间格式处理、字段脱敏等。
2.数据库字段加密带来的问题:不好做模糊查询。网上有解决方案(将一个字段拆分多个存储,查询时通过加密后匹配这些字段)不过这个得看场景了

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值