mybatis数据库字段加解密

Posted by Clear Blog on December 9, 2018
  1. 使用数据库自带的加密方法 比如说mysql中,
    • 加密 ````sql mysql> select hex(AES_ENCRYPT(‘xuguangwu’, ‘aesKey’)) from dual; +—————————————–+ | hex(AES_ENCRYPT(‘xuguangwu’, ‘aesKey’)) | +—————————————–+ | 8BD68E8887E31167D9F6EB578DA60C21 | +—————————————–+ 1 row in set (0.00 sec)
1
2
3
4
5
6
7
8
9
* 解密
````sql
mysql> SELECT AES_DECRYPT(unhex('8BD68E8887E31167D9F6EB578DA60C21'), 'aesKey') username FROM DUAL;
+-----------+
| username  |
+-----------+
| xuguangwu |
+-----------+
1 row in set (0.01 sec)
  1. 使用Mybatis的TypeAlias和TypeHandler,对MySql数据库表的字段进行加解密 使用MyBatis TypeHandler可以在 JavaType 和 JdbcType 中互相转换的特性, 拦截 JavaType 为 AESEncrypt 的SQL,在预处理语句(PreparedStatement)中设置参数时自动加密,并在结果集(ResultSet)中取值时自动解密。
  • alias
    1
    2
    3
    4
    
    import org.apache.ibatis.type.Alias;
    @Alias("AESEncrypt")
    public class AESEncrypt {
    }
    
  • handler ````java @MappedTypes(AESEncrypt.class) public class EncryptTypeHandler extends BaseTypeHandler { private static final Logger LOG = LoggerFactory.getLogger(EncryptTypeHandler.class); private static final String aesKey = "emosskgkey"; /**
    • 用于定义在Mybatis设置参数时该如何把Java类型的参数转换为对应的数据库类型 *
    • @param ps 当前的PreparedStatement对象
    • @param i 当前参数的位置
    • @param parameter 当前参数的Java对象
    • @param jdbcType 当前参数的数据库类型
    • @throws SQLException */ @Override public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { // 只要 parameter 非空都进行加密 LOG.info(“setNonNullParameter index <{}>, param <{}> “, i, parameter); ps.setString(i, EndecryptUtil.AESEncrypt(parameter, aesKey)); }

    /**

    • 用于在Mybatis获取数据结果集时如何把数据库类型转换为对应的Java类型 *
    • @param rs 当前的结果集
    • @param columnName 当前的字段名称
    • @return 转换后的Java对象
    • @throws SQLException */ @Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { String r = rs.getString(columnName); return r == null ? null : EndecryptUtil.AESDecrypt(r, aesKey); }

    /**

    • 用于在Mybatis通过字段位置获取字段数据时把数据库类型转换为对应的Java类型 *
    • @param rs 当前的结果集
    • @param columnIndex 当前字段的位置
    • @return 转换后的Java对象
    • @throws SQLException */ @Override public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { String r = rs.getString(columnIndex); return r == null ? null : EndecryptUtil.AESDecrypt(r, aesKey); }

    /**

    • 用于Mybatis在调用存储过程后把数据库类型的数据转换为对应的Java类型 *
    • @param cs 当前的CallableStatement执行后的CallableStatement
    • @param columnIndex 当前输出参数的位置
    • @return
    • @throws SQLException */ @Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { String r = cs.getString(columnIndex); // 兼容待修复的数据 return r == null ? null : EndecryptUtil.AESDecrypt(r, aesKey); } } ````
  • xml ````xml
insert into user_t (id, username, password) values (#{id,jdbcType=BIGINT}, #{username,jdbcType=VARCHAR}, #{password, javaType=AESEncrypt, jdbcType=VARCHAR})

````