栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

敏感数据统一国标(SM4)加解密Mybatis-Plus/Mybatis实现方案

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

敏感数据统一国标(SM4)加解密Mybatis-Plus/Mybatis实现方案

算法背景

SM4分组密码算法是2012年就推出实施的,是我国自主设计的分组对称密码算法,用于实现数据的加密/解密运算,以保证数据和信息的机密性。SM4算法与AES算法具有相同的密钥长度分组长度为128比特,因此在安全性上是高于3DES算法。

具体方案

前提:国标加密工具类尽量不要去重复造轮子,hutool有现成的工具类(当然自己实现也是可以)


  cn.hutool
  hutool-crypto
  5.7.8
 
 
   org.bouncycastle
   bcprov-jdk15to18
   1.69

1创建基于Mybatis的BaseTypeHandler通用处理类
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.symmetric.SM4;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.nio.charset.StandardCharsets;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


@Slf4j
public class TestDataTypeHandler extends BaseTypeHandler {
    
    private static final String SM4_KEY = "aabbccddeeffgghh";

    
    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, String parameter, JdbcType jdbcType) {
        //不处理空字符串
        if(StringUtils.isBlank(parameter)){
            return;
        }
        try {
            SM4 sm4 = SmUtil.sm4(SM4_KEY.getBytes(StandardCharsets.UTF_8));
            String encrypt = sm4.encryptHex(parameter,StandardCharsets.UTF_8);
            log.info("数据:{},加密{}",parameter,encrypt);
            preparedStatement.setString(i, encrypt);
        } catch (Exception e) {
            log.error("typeHandler加密异常:" + e);
        }
    }

    
    @Override
    public String getNullableResult(ResultSet resultSet, String columnName) throws SQLException {
        String col = resultSet.getString(columnName);
        //不处理空字符串
        if(StringUtils.isBlank(col)){
            return col;
        }
        try {
            //16位key
            SM4 sm4 = SmUtil.sm4(SM4_KEY.getBytes(StandardCharsets.UTF_8));
            String plain = sm4.decryptStr(col,StandardCharsets.UTF_8);
            log.info("数据:{},解密{}",col,plain);
            return plain;
        } catch (Exception e) {
            log.error("数据非sms加密");
        }
        return col;
    }

    
    @Override
    public String getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException {
        return resultSet.getString(columnIndex);
    }

    
    @Override
    public String getNullableResult(CallableStatement callableStatement, int columnIndex) throws SQLException {
        return callableStatement.getString(columnIndex);
    }
}

2.针对于Mybatis-plus用法
  1. 需要在@TableName注解中,设置autoResultMap参数为true
  2. 在需要加解密的字段上,加上注解 @TableField(typeHandler = SensitiveDataTypeHandler.class)
  3. 应用范围:所有MP生成的service与mapper,在进行操作数据的时候会自动应用
@TableName(autoResultMap = true)
public class TestLog extends Model {
  
  	...
    ...
    @TableField(typeHandler = TestDataTypeHandler .class)
    private String mobile;
}
3.针对于Mybatis的用法
  1. SQL注解方式,配置 Result 示例:
 @Select("SELECT * FROM test_log")
 @Results(id= "resultMap", value = {
       @Result(column = "mobile", property = "mobile", typeHandler = TestDataTypeHandler .class)
 })
 List listAll();
  1. XML方式,配置 typeHandler 示例:

    



    SELECT * FROM test_log

注意
  1. 不支持加密自定义入参,自定义入参需要手动加密后入库;(包括自定义查询/保存/修改;推荐使用mybatis-plus操作类实现,可自动处理)
  2. 加密字段不支持模糊查询
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/859442.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号