在实际生产项目中,经常需要对如身份证信息、手机号、真实姓名等的敏感数据进行加密数据库存储,但在业务代码中对敏感信息进行手动加解密则十分不优雅,甚至会存在错加密、漏加密、业务人员需要知道实际的加密规则等的情况。
本文将介绍使用springboot+mybatis拦截器+自定义注解的形式对敏感数据进行存储前拦截加密的详细过程。
一、什么是Mybatis Plugin
在mybatis官方文档中,对于Mybatis plugin的的介绍是这样的:
MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:
//语句执行拦截
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
// 参数获取、设置时进行拦截
ParameterHandler (getParameterObject, setParameters)
// 对返回结果进行拦截
ResultSetHandler (handleResultSets, handleOutputParameters)
//sql语句拦截
StatementHandler (prepare, parameterize, batch, update, query)
简而言之,即在执行sql的整个周期中,我们可以任意切入到某一点对sql的参数、sql执行结果集、sql语句本身等进行切面处理。基于这个特性,我们便可以使用其对我们需要进行加密的数据进行切面统一加密处理了(分页插件 pageHelper 就是这样实现数据库分页查询的)。
二、实现基于注解的敏感信息加解密拦截器
2.1 实现思路
对于数据的加密与解密,应当存在两个拦截器对数据进行拦截操作
参照官方文档,因此此处我们应当使用ParameterHandler拦截器对入参进行加密
使用ResultSetHandler拦截器对出参进行解密操作。
目标需要加密、解密的字段可能需要灵活变更,此时我们定义一个注解,对需要加密的字段进行注解,那么便可以配合拦截器对需要的数据进行加密与解密操作了。
mybatis的interceptor接口有以下方法需要实现。
public interface Interceptor {
//主要参数拦截方法
Object intercept(Invocation invocation) throws Throwable;
//mybatis插件链
default Object plugin(Object target) {return Plugin.wrap(target, this);}
//自定义插件配置文件方法
default void setProperties(Properties properties) {}
}
2.2 定义需要加密解密的敏感信息注解
定义注解敏感信息类(如实体类POJO\PO)的注解
/**
* 注解敏感信息类的注解
*/
@Inherited
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface SensitiveData {
}
定义注解敏感信息类中敏感字段的注解
/**
* 注解敏感信息类中敏感字段的注解
*/
@