SM4分组密码算法是2012年就推出实施的,是我国自主设计的分组对称密码算法,用于实现数据的加密/解密运算,以保证数据和信息的机密性。SM4算法与AES算法具有相同的密钥长度分组长度为128比特,因此在安全性上是高于3DES算法。
具体方案前提:国标加密工具类尽量不要去重复造轮子,hutool有现成的工具类(当然自己实现也是可以)
1创建基于Mybatis的BaseTypeHandler通用处理类cn.hutool hutool-crypto 5.7.8 org.bouncycastle bcprov-jdk15to18 1.69
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 BaseTypeHandler2.针对于Mybatis-plus用法{ 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); } }
- 需要在@TableName注解中,设置autoResultMap参数为true
- 在需要加解密的字段上,加上注解 @TableField(typeHandler = SensitiveDataTypeHandler.class)
- 应用范围:所有MP生成的service与mapper,在进行操作数据的时候会自动应用
@TableName(autoResultMap = true) public class TestLog extends Model3.针对于Mybatis的用法{ ... ... @TableField(typeHandler = TestDataTypeHandler .class) private String mobile; }
- SQL注解方式,配置 Result 示例:
@Select("SELECT * FROM test_log")
@Results(id= "resultMap", value = {
@Result(column = "mobile", property = "mobile", typeHandler = TestDataTypeHandler .class)
})
List listAll();
- XML方式,配置 typeHandler 示例:
注意SELECT * FROM test_log
- 不支持加密自定义入参,自定义入参需要手动加密后入库;(包括自定义查询/保存/修改;推荐使用mybatis-plus操作类实现,可自动处理)
- 加密字段不支持模糊查询



