Skip to content

18. 加解密使用说明

针对某些业务表中包含的一些如身份证号、联系方式等的敏感字段,libra-client提供加解密功能,将敏感字段以密文形式存储在数据库,业务系统通过libra-client读取这部分数据时,获取到的是解密后的明文,通过其他数据库访问工具则无法获取密文对应的真实含义。

18.1 使用

​ 在encryption.xml或encryption.yaml中配置表中需进行加密的字段及使用的加密算法,加密算法内置国密对称加密算法sm4-cbcsm4-ecb,同时提供扩展接口,供用户自行实现或对接加密机。encryption.xml示例配置如下:

xml
<!--加密对象,名称为逻辑库名.表名-->
<encryption name="TestDb.rb_client" defaultType="sm4-cbc">
    <!--相同加密类型的加密字段以,分隔-->
   <columns value="client_name,phone" type="sm4-ecb"/>
   <!--加密类型缺省时,生效defaultType-->
   <columns value="id_card"/>
</encryption>
<encryption name="TestDb.rb_client_bak" defaultType="sm4-cbc">
   <columns value="client_name"/>
</encryption>

配置项介绍:

一级标签二级标签属性描述备选值是否必输
encryptionname加密属性名称,为逻辑库名.表名
defaultType表级加密算法类型,优先级低于列级加密算法sm4-ecb,sm4-cbc或用户自行实现的算法别名
columnsvalue列名称,多个列以,分隔
type列级加密算法类型,缺省时生效表级加密算法sm4-ecb,sm4-cbc或用户自行实现的算法别名

使用加密功能时,还可以通过server.xml中的system配置设置是否开启加解密结果缓存,减少与加密系统的交互次数。

xml
<!--是否启用加解密结果缓存,默认关闭-->
<property name="useEncryptionCache">true</property>

18.2 自定义加密算法

​ libra-client定义了加密适配接口com.dcits.libra.dac.encryption.spi.EncryptAlgorithm,业务应用可自行实现其中的加密与解密方法。EncryptAlgorithm接口如下:

java
public interface EncryptAlgorithm<I, O> {

    /**
     * @return encrypt algorithm type
     */
    String getType();

    /**
     * @param plainValue
     * @return
     */
    O encrypt(I plainValue);

    /**
     * @param cipherValue
     * @return
     */
    I decrypt(O cipherValue);

    /**
     * batch operation
     *
     * @param plainValues
     * @return
     */
    Map<String, O> encrypt(Set<I> plainValues);

    /**
     * batch operation
     *
     * @param cipherValues
     * @return
     */
    Map<String, I> decrypt(Set<O> cipherValues);
}

对于业务应用自行实现的加密算法,在项目的classpath的META-INF/services路径下创建com.dcits.libra.client.encryption.spi.EncryptAlgorithm文件,并将实现类的全类名填写在该文件中,多个实现类以换行符分隔,以保证算法可以被spi类加载器加载。

18.3 使用限制

  • 不支持对加密字段进行逻辑运算操作
  • 不支持加密字段的聚合操作
  • 因字段加密是在sql解析过程即路由之前进行的加解密,不支持以加密字段作为分片字段
  • 若加密字段为两张ER表的关联键,加密字段在两张表中使用的加密算法应保持一致
  • 子查询语句仅支持单表嵌套子查询
  • 对于后端为oracle库的使用场景,查询语句的查询字段不能为*,且多表联查时需要标明列的所属表名。
  • 仅支持两表join,不支持两表以上的表join
  • 后端为oracle库时,不支持复杂sql的加解密操作