Skip to content

drtrang/typehandlers-encrypt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MyBatis Type Handlers for Encrypt

Build Status Coverage Status Maven Central License

介绍

应公司安全部门要求,需要对数据库中的敏感信息做加密处理。由于此次需求涉及的字段较多,手动加解密颇为不便且改动较大,一个更加简单、通用的解决方案势在必行。

typehandlers-encrypt 项目在这种背景下诞生,用户使用时无需更改业务代码,仅需少量配置即可实现数据库指定字段的加解密操作,大大减小了对用户的影响。

实现原理

typehandlers-encrypt 基于 MyBatis 的 TypeHandler 开发,通过 TypeHandler 可以在 JavaType 和 JdbcType 中互相转换的特性,拦截 JavaType 为 com.github.trang.typehandlers.alias.Encrypt 的 SQL,在预处理语句(PreparedStatement)中设置参数时自动加密,并在结果集(ResultSet)中取值时自动解密。

注:由于依赖 MyBatis,使用时需要将 EncryptTypeHandlerEncrypt 注册到 MyBatis,否则无法生效,注册方式见 声明 EncryptTypeHandler

应用

依赖

<dependency>
    <groupId>com.github.drtrang</groupId>
    <artifactId>typehandlers-encrypt</artifactId>
    <version>1.1.1</version>
</dependency>

声明 EncryptTypeHandler

1. 单独使用 MyBatis

<!-- mybatis-config.xml -->
<typeAliases>
    <package name="com.github.trang.typehandlers.alias" />
</typeAliases>

<typeHandlers>
    <package name="com.github.trang.typehandlers.type" />
</typeHandlers>

2. 与 Spring 结合

@Bean
public SqlSessionFactory sqlSessionFactory(Configuration config) {
    SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
    factory.setTypeAliasesPackage("com.github.trang.typehandlers.alias");
    factory.setTypeHandlersPackage("com.github.trang.typehandlers.type");
    return factory.getObject();
}

3. 与 SpringBoot 结合

##application.yml
mybatis:
    type-aliases-package: com.github.trang.typehandlers.alias
    type-handlers-package: com.github.trang.typehandlers.type

注:以上配置方式任选其一即可,请根据实际情况选择。

使用 EncryptTypeHandler

<!-- select: 在 resultMap 或 SQL 中需要加密的字段上声明 `javaType="encrypt"` -->
<resultMap id="BaseResultMap" type="user">
    <id column="id" property="id" jdbcType="BIGINT" />
    <result column="username" javaType="string" jdbcType="VARCHAR" property="username" />
    <result column="password" javaType="encrypt" jdbcType="VARCHAR" property="password" />
</resultMap>

<!-- insert: 在 SQL 中需要加密的字段上声明 `javaType="encrypt"` -->
<insert id="insert" parameterType="user">
    insert into user (id, username, password)
    values (#{id,jdbcType=BIGINT}, #{username,jdbcType=VARCHAR}, #{password, javaType=encrypt, jdbcType=VARCHAR})
</insert>

<!-- update: 在 SQL 中需要加密的字段上声明 `javaType="encrypt"` -->
<update id="update" parameterType="user">
    update user set password=#{password, javaType=encrypt, jdbcType=VARCHAR} where id=#{id}
</update>

进阶

typehandlers-encrypt 内置了 AES 加密算法与默认的 16 位密钥,支持开箱即用,但用户也可以自定义加密算法和密钥,只需要在配置文件中声明对应的配置即可。需要注意,两者同时配置时,要声明在同一文件里

配置示例:

encrypt.private.key=xxx
encrypt.class.name=com.github.trang.typehandlers.crypt.SimpleEncrypt

配置文件查找

方式一:项目启动时,会在项目的 Classpath 中依次查找名称为 encryptproperties/config-commonproperties/configconfigapplication 的 Properties 文件,直到文件存在且文件中包含名称为 encrypt.private.key 的属性时停止。

方式二:如果项目中不存在以上文件,且不想单独新增,也可以在项目启动时调用 ConfigUtil.bundleNames("xxx") 来指定要读取的文件,这时只会从用户给定的文件中查找。

当没有查找到相应配置时,项目会使用内置的默认配置。

自定义密钥

typehandlers-encrypt 支持自定义密钥,只需在配置文件中声明即可。

encrypt.private.key=xxx

自定义加密算法

typehandlers-encrypt 默认的加密算法是 AES 对称加密,如果默认算法不满足实际需求,用户可以自己实现 com.github.trang.typehandlers.crypt.Crypt 接口,并在配置文件中声明实现类的全路径。

encrypt.class.name=com.github.trang.typehandlers.crypt.SimpleEncrypt

硬广

目前项目已开源,并上传到 Github,大家感兴趣的话可以阅读源码。Github 中有配套的 Demo 演示 typehandlers-encrypt-demo,其中包括 typehandlers-encrypt 完整的使用方式,可以作为参考。

如果有问题,可以在 Github 上提 ISSUE,或者 QQ 交流,以下是联系方式:
我的 Github 主页:https://github.com/drtrang
该项目的 Github 地址:https://github.com/drtrang/typehandlers-encrypt
配套 Demo 的 Github 地址:https://github.com/drtrang/typehandlers-encrypt-demo
BeanCopier 工具:https://github.com/drtrang/Copiers
QQ:349096849

注意:

  1. 目前 EncryptTypeHandler 只支持 JavaType 为 String 的情形,如有其它需求,请及时联系我。
  2. 加密时字段只过滤 null 值,非 null 的字段不做任何处理直接加密。