Mybatis插件应用之数据脱敏(数据脱敏java)

  本篇文章为你整理了Mybatis插件应用之数据脱敏(数据脱敏java)的详细内容,包含有数据脱敏sql 数据脱敏java mybatis tidb mybatis数据 Mybatis插件应用之数据脱敏,希望能帮助你了解 Mybatis插件应用之数据脱敏。

  

利用mybatis中的plugin(拦截器,底层基于jdk动态代理实现),并结合自定义注解,实现对某些重要字段的加密和解密。

 

  
@Intercepts({

   @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),

   @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})

  public class EncryptInterceptor implements Interceptor {

   * 加密标识

   private static final int ENCRYPT_DATA = 0;

   * 解密标识

   private static final int DECRYPT_DATA = 1;

   @Override

   public Object intercept(Invocation invocation) throws Throwable {

   Object result;

   //根据拦截的方法判断对字段加密还是解密

   if (Objects.equals(invocation.getMethod().getName(), "query")) {

   //对查询结果解密

   result = decryptData(invocation);

   } else {

   //对插入数据加密

   result = encryptData(invocation);

   return result;

   * 对查询结果解密入口

   * @param invocation

   * @return

   * @throws Exception

   private Object decryptData(Invocation invocation) throws Exception {

   System.out.println("解密...");

   //取出查询的结果

   Object resultObj = invocation.proceed();

   if (Objects.isNull(resultObj)) {

   return null;

   //结果为数组

   if (resultObj instanceof List) {

   List ? data = (List ? ) resultObj;

   if (CollectionUtils.isEmpty(data) !findSensitiveAnnotation(data.get(0))) {

   return null;

   for (Object item : data) {

   handle(item, DECRYPT_DATA);

   return resultObj;

   //结果为单个对象

   if (findSensitiveAnnotation(resultObj)) {

   handle(resultObj, DECRYPT_DATA);

   return resultObj;

   * 对插入数据加密入口

   * @param invocation

   * @return

   * @throws Exception

   private Object encryptData(Invocation invocation) throws Exception {

   System.out.println("加密...");

   Object param = invocation.getArgs()[1];

   if (Objects.isNull(param) !findSensitiveAnnotation(param)) {

   return null;

   System.out.println("原插入对象:" + param);

   handle(param, ENCRYPT_DATA);

   System.out.println("加密后对象:" + param);

   return invocation.proceed();

   * 判断类是否包含@SensitiveData注解

   * @param obj

   * @return

   private boolean findSensitiveAnnotation(Object obj) {

   return Objects.nonNull(AnnotationUtils.findAnnotation(obj.getClass(), SensitiveData.class));

   * 对数据解密或解密

   * @param data

   * @param flag

   * @param T

   * @throws Exception

   public T void handle(T data, int flag) throws Exception {

   //遍历字段

   for (Field field : data.getClass().getDeclaredFields()) {

   //取出被Encrypt注解的字段

   if (Objects.isNull(field.getAnnotation(Encrypt.class))) {

   continue;

   field.setAccessible(true);

   Object val = field.get(data);

   if (val instanceof String) {

   if (flag == DECRYPT_DATA) {

   field.set(data, EncryptUtil.decrypt((String) val));

   } else if (flag == ENCRYPT_DATA) {

   field.set(data, EncryptUtil.encrypt((String) val));

   } else {

   return;

   @Override

   public Object plugin(Object target) {

   return Interceptor.super.plugin(target);

   @Override

   public void setProperties(Properties properties) {

   Interceptor.super.setProperties(properties);

  

 

 

  
private static final String DEFAULT_V = "6859505890402435";

   private static final String KEY = "***";

   private static final String ALGORITHM = "AES";

   private static SecretKeySpec getKey() {

   byte[] arrBTmp = EncryptUtil.KEY.getBytes();

   // 创建一个空的16位字节数组(默认值为0)

   byte[] arrB = new byte[16];

   for (int i = 0; i arrBTmp.length i arrB.length; i++) {

   arrB[i] = arrBTmp[i];

   return new SecretKeySpec(arrB, ALGORITHM);

   * 加密

   * @param content

   * @return

   * @throws Exception

   public static String encrypt(String content) throws Exception {

   final Base64.Encoder encoder = Base64.getEncoder();

   SecretKeySpec keySpec = getKey();

   Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

   IvParameterSpec iv = new IvParameterSpec(DEFAULT_V.getBytes());

   cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);

   byte[] encrypted = cipher.doFinal(content.getBytes());

   return encoder.encodeToString(encrypted);

   * 解密

   * @param content

   * @return

   * @throws Exception

   public static String decrypt(String content) throws Exception {

   final Base64.Decoder decoder = Base64.getDecoder();

   SecretKeySpec keySpec = getKey();

   Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

   IvParameterSpec iv = new IvParameterSpec(DEFAULT_V.getBytes());

   cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);

   byte[] base64 = decoder.decode(content);

   byte[] original = cipher.doFinal(base64);

   return new String(original);

  }

 

 

  
public Result insert(@RequestBody User user) {

   boolean result = encryptService.insert(user);

   return Result.success(result);

  }

 

 

  


 ?xml version="1.0" encoding="UTF-8" ? 

 

   !DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"

   mapper namespace="cn.com.dork.study.encrypt.EncryptMapper"

   insert id="insert" parameterType="cn.com.dork.test.User"

   insert into test(name,pwd) values (#{name},#{pwd})

   /insert

   select id="getUser" resultType="cn.com.dork.test.User"

   SELECT id, name, pwd

   FROM test

   /select

   /mapper

 

  以上就是Mybatis插件应用之数据脱敏(数据脱敏java)的详细内容,想要了解更多 Mybatis插件应用之数据脱敏的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: