Browse Source

数据库字段加密解密拦截

gaodm 5 năm trước cách đây
mục cha
commit
b9cd645a14

+ 0 - 3
aipt-service/src/main/java/com/diagbot/aop/CryptAspect.java

@@ -103,17 +103,14 @@ public class CryptAspect {
             return str;
         }
         if (isSingle == null) {
-            //todo 加密实现
             str = CryptUtil.encrypt_char(str);
             return str;
         }
         if (isSingle && set != null && !set.isEmpty()) {
-            //todo 加密实现
             str = CryptUtil.encrypt_char(str);
             return str;
         }
         if (!isSingle && set != null && !set.isEmpty() && set.contains(name)) {
-            //todo 加密实现
             str = CryptUtil.encrypt_char(str);
             return str;
         }

+ 61 - 0
common/src/main/java/com/diagbot/util/EnDecodeUtil.java

@@ -0,0 +1,61 @@
+package com.diagbot.util;
+
+import sun.misc.BASE64Decoder;
+import sun.misc.BASE64Encoder;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * @Description: 加解密工具类
+ * @author: ztg
+ * @time: 2018/11/8 14:38
+ */
+public class EnDecodeUtil {
+
+    /**
+     * 采用BASE64算法对字符串进行加密
+     * @param str 原字符串
+     * @return 加密后的字符串
+     */
+    public static String encode(String str) {
+        byte[] b = null;
+        String s = null;
+        try {
+            b = str.getBytes("utf-8");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        if (b != null) {
+            s = new BASE64Encoder().encode(b);
+        }
+        return s;
+    }
+
+    /**
+     * 字符串解密,采用BASE64的算法
+     * @param s 需要解密的字符串
+     * @return 解密后的字符串
+     */
+    public static String decode(String s) {
+        byte[] b = null;
+        String result = null;
+        if (s != null) {
+            BASE64Decoder decoder = new BASE64Decoder();
+            try {
+                b = decoder.decodeBuffer(s);
+                result = new String(b, "utf-8");
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return result;
+    }
+
+
+    public static void main(String[] args) {
+        String abc = "201811081616";
+        String c = encode(abc);
+        System.out.println(c);
+        System.out.println(decode(c));
+    }
+}

+ 244 - 0
knowledgeman-service/src/main/java/com/diagbot/aop/CryptAspect.java

@@ -0,0 +1,244 @@
+package com.diagbot.aop;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.diagbot.annotation.CryptField;
+import com.diagbot.dto.RespDTO;
+import com.diagbot.util.CryptUtil;
+import com.diagbot.util.RespDTOUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.context.annotation.Configuration;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @Description: 数据库加解密
+ * @author: gaodm
+ * @time: 2019/12/31 13:17
+ */
+@Aspect
+@Slf4j
+@Configuration
+public class CryptAspect {
+
+    //切所有mapper
+    @Pointcut("execution(* com.diagbot.web..*.*(..))")
+    public void pointcut() {
+    }
+
+    @Around("pointcut()")
+    public Object aroundReturning(ProceedingJoinPoint joinPoint) throws Throwable {
+        //获取方法参数
+        Object[] args = joinPoint.getArgs();
+        //入参加密
+        for (Object parameter : args) {
+            if (!isNotCrypt(parameter)) {
+                // 只支持bean
+                beanEncrypt(parameter);
+            }
+        }
+        //执行方法
+        Object proceed = joinPoint.proceed(args);
+        if (null == proceed) {
+            return null;
+        }
+        //出参解密
+        if (proceed instanceof RespDTO) {
+            RespDTO respDTO = (RespDTO) proceed;
+            if (RespDTOUtil.respIsOK(respDTO)) {
+                if (respDTO instanceof IPage) {
+                    Page page = (Page) respDTO.data;
+                    beanDecrypt(page.getRecords());
+                } else {
+                    beanDecrypt(respDTO.data);
+                }
+            }
+        }
+
+        return proceed;
+    }
+
+
+    /**
+     * 判断是否需要加解密
+     *
+     * @param o
+     * @return
+     */
+    private boolean isNotCrypt(Object o) {
+        return o == null || o instanceof Double || o instanceof Integer || o instanceof Long || o instanceof Boolean;
+    }
+
+    /**
+     * String 加密
+     *
+     * @param str
+     * @return
+     * @throws Exception
+     */
+    private String stringEncrypt(String str) throws Exception {
+        return stringEncrypt(null, str, null, null);
+    }
+
+    /**
+     * String 加密
+     *
+     * @param name
+     * @param str
+     * @param set
+     * @param isSingle
+     * @return
+     * @throws Exception
+     */
+    private String stringEncrypt(String name, String str, Set<String> set, Boolean isSingle) throws Exception {
+        if (StringUtils.isBlank(str)) {
+            return str;
+        }
+        if (isSingle == null) {
+            str = CryptUtil.encrypt_char(str);
+            return str;
+        }
+        if (isSingle && set != null && !set.isEmpty()) {
+            str = CryptUtil.encrypt_char(str);
+            return str;
+        }
+        if (!isSingle && set != null && !set.isEmpty() && set.contains(name)) {
+            str = CryptUtil.encrypt_char(str);
+            return str;
+        }
+
+        return str;
+    }
+
+
+    /**
+     * String 解密
+     *
+     * @param str
+     * @return
+     */
+    private String stringDecrypt(String str) {
+        if (StringUtils.isBlank(str)) {
+            return str;
+        }
+        str = CryptUtil.decrypt_char(str);
+
+        return str;
+    }
+
+    /**
+     * list 加密
+     *
+     * @param list
+     * @param bo
+     * @return
+     * @throws Exception
+     */
+    private List listEncrypt(List list, Boolean bo) throws Exception {
+        for (int i = 0; i < list.size(); i++) {
+            Object listValue = list.get(i);
+            // 判断不需要解析的类型
+            if (isNotCrypt(listValue) || listValue instanceof Map) {
+                break;
+            }
+            if (listValue instanceof String && bo) {
+                list.set(i, stringEncrypt((String) listValue));
+                continue;
+            }
+            beanEncrypt(listValue);
+        }
+
+        return list;
+    }
+
+    /**
+     * list 解密
+     *
+     * @param list
+     * @param bo
+     * @return
+     * @throws Exception
+     */
+    private List listDecrypt(List list, Boolean bo) throws Exception {
+        for (int i = 0; i < list.size(); i++) {
+            Object listValue = list.get(i);
+            // 判断不需要解析的类型 获得
+            if (isNotCrypt(listValue) || listValue instanceof Map) {
+                break;
+            }
+            if (listValue instanceof String && bo) {
+                list.set(i, stringDecrypt((String) listValue));
+                continue;
+            }
+            beanDecrypt(listValue);
+        }
+
+        return list;
+    }
+
+    /**
+     * bean 加密
+     *
+     * @param val
+     * @throws Exception
+     */
+    private void beanEncrypt(Object val) throws Exception {
+        Class objClazz = val.getClass();
+        Field[] objFields = objClazz.getDeclaredFields();
+        for (Field field : objFields) {
+            CryptField cryptField = field.getAnnotation(CryptField.class);
+            if (cryptField != null && cryptField.encrypt()) {
+                field.setAccessible(true);
+                Object fieldValue = field.get(val);
+                if (fieldValue == null) {
+                    continue;
+                }
+                if (field.getType().equals(String.class)) {
+                    field.set(val, stringEncrypt((String) fieldValue));
+                    continue;
+                }
+                if (field.getType().equals(List.class)) {
+                    field.set(val, listEncrypt((List) fieldValue, Boolean.TRUE));
+                    continue;
+                }
+            }
+        }
+    }
+
+    /**
+     * bean 解密
+     *
+     * @param val
+     * @throws Exception
+     */
+    private void beanDecrypt(Object val) throws Exception {
+        Class objClazz = val.getClass();
+        Field[] objFields = objClazz.getDeclaredFields();
+        for (Field field : objFields) {
+            CryptField cryptField = field.getAnnotation(CryptField.class);
+            if (cryptField != null && cryptField.decrypt()) {
+                field.setAccessible(true);
+                Object fieldValue = field.get(val);
+                if (fieldValue == null) {
+                    continue;
+                }
+                if (field.getType().equals(String.class)) {
+                    field.set(val, stringDecrypt((String) fieldValue));
+                    continue;
+                }
+                if (field.getType().equals(List.class)) {
+                    field.set(val, listDecrypt((List) fieldValue, Boolean.TRUE));
+                    continue;
+                }
+            }
+        }
+    }
+}

+ 441 - 441
knowledgeman-service/src/main/java/com/diagbot/aop/CryptInterceptor.java

@@ -1,443 +1,443 @@
-package com.diagbot.aop;
-
-import com.diagbot.annotation.CryptField;
-import com.diagbot.util.CryptUtil;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.ibatis.binding.MapperMethod;
-import org.apache.ibatis.executor.Executor;
-import org.apache.ibatis.mapping.MappedStatement;
-import org.apache.ibatis.plugin.Interceptor;
-import org.apache.ibatis.plugin.Intercepts;
-import org.apache.ibatis.plugin.Invocation;
-import org.apache.ibatis.plugin.Plugin;
-import org.apache.ibatis.plugin.Signature;
-import org.apache.ibatis.session.ResultHandler;
-import org.apache.ibatis.session.RowBounds;
-import org.apache.ibatis.session.defaults.DefaultSqlSession;
-import org.springframework.stereotype.Component;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * @Description: 数据库加解密
- * @author: gaodm
- * @time: 2019/12/30 18:38
- */
-@Intercepts({
-        @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }),
-        @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class })
-})
-@Component
-public class CryptInterceptor implements Interceptor {
-
-    private static final String PARAM = "param";
-
-    private static final String PARAM_TYPE_LIST = "list";
-
-    private static final String PARAM_TYPE_COLLECTION = "collection";
-
-    private static final String MAPPEDSTATEMENT_ID_SEPERATOR = ".";
-
-    /**
-     * 适用于加密判断
-     */
-    private static final ConcurrentHashMap<String, Set<String>> METHOD_PARAM_ANNOTATIONS_MAP = new ConcurrentHashMap<>();
-    /**
-     * 适用于解密判断
-     */
-    private static final ConcurrentHashMap<String, Boolean> METHOD_ANNOTATIONS_MAP = new ConcurrentHashMap<>();
-
-    public CryptInterceptor() {
-
-    }
-
-    @Override
-    public Object intercept(Invocation invocation) throws Throwable {
-        Object[] args = invocation.getArgs();
-        // 入参
-        Object parameter = args[1];
-        MappedStatement statement = (MappedStatement) args[0];
-        // 判断是否需要解析
-        if (!isNotCrypt(parameter)) {
-            // 单参数 string
-            if (parameter instanceof String) {
-                args[1] = stringEncrypt((String) parameter, getParameterAnnotations(statement));
-                // 单参数 list
-            } else if (parameter instanceof DefaultSqlSession.StrictMap) {
-                DefaultSqlSession.StrictMap<Object> strictMap = (DefaultSqlSession.StrictMap<Object>) parameter;
-                for (Map.Entry<String, Object> entry : strictMap.entrySet()) {
-                    if (entry.getKey().contains(PARAM_TYPE_COLLECTION)) {
-                        continue;
-                    }
-                    if (entry.getKey().contains(PARAM_TYPE_LIST)) {
-                        Set<String> set = getParameterAnnotations(statement);
-                        listEncrypt((List) entry.getValue(), !set.isEmpty());
-                    }
-                }
-                // 多参数
-            } else if (parameter instanceof MapperMethod.ParamMap) {
-                MapperMethod.ParamMap<Object> paramMap = (MapperMethod.ParamMap<Object>) parameter;
-                Set<String> set = getParameterAnnotations(statement);
-                boolean setEmpty = set.isEmpty();
-                // 解析每一个参数
-                for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
-                    // 判断不需要解析的类型 不解析map
-                    if (isNotCrypt(entry.getValue()) || entry.getValue() instanceof Map || entry.getKey().contains(PARAM)) {
-                        continue;
-                    }
-                    // 如果string
-                    if (entry.getValue() instanceof String) {
-                        entry.setValue(stringEncrypt(entry.getKey(), (String) entry.getValue(), set));
-                        continue;
-                    }
-                    boolean isSetValue = !setEmpty && set.contains(entry.getKey());
-                    // 如果 list
-                    if (entry.getValue() instanceof List) {
-                        listEncrypt((List) entry.getValue(), isSetValue);
-                        continue;
-                    }
-                    beanEncrypt(entry.getValue());
-                }
-                // bean
-            } else {
-                beanEncrypt(parameter);
-            }
-        }
-
-        // 获得出参
-        Object returnValue = invocation.proceed();
-
-        // 出参解密
-        if (isNotCrypt(returnValue)) {
-            return returnValue;
-        }
-        Boolean bo = getMethodAnnotations(statement);
-        if (returnValue instanceof String && bo) {
-            return stringDecrypt((String) returnValue);
-        }
-        if (returnValue instanceof List) {
-            listDecrypt((List) returnValue, bo);
-            return returnValue;
-        }
-
-        return returnValue;
-    }
-
-    @Override
-    public Object plugin(Object target) {
-        return Plugin.wrap(target, this);
-    }
-
-    @Override
-    public void setProperties(Properties properties) {
-
-    }
-
-    /**
-     * 获取 方法上的注解
-     *
-     * @param statement
-     * @return
-     * @throws ClassNotFoundException
-     */
-    private Boolean getMethodAnnotations(MappedStatement statement) throws ClassNotFoundException {
-        final String id = statement.getId();
-        Boolean bo = METHOD_ANNOTATIONS_MAP.get(id);
-        if (bo != null) {
-            return bo;
-        }
-        Method m = getMethodByMappedStatementId(id);
-        if (m == null) {
-            return Boolean.FALSE;
-        }
-        final CryptField cryptField = m.getAnnotation(CryptField.class);
-        // 如果允许解密
-        if (cryptField != null && cryptField.decrypt()) {
-            bo = Boolean.TRUE;
-        } else {
-            bo = Boolean.FALSE;
-        }
-        Boolean bo1 = METHOD_ANNOTATIONS_MAP.putIfAbsent(id, bo);
-        if (bo1 != null) {
-            bo = bo1;
-        }
-
-        return bo;
-    }
-
-    /**
-     * 获取 方法参数上的注解
-     *
-     * @param statement
-     * @return
-     * @throws ClassNotFoundException
-     */
-    private Set<String> getParameterAnnotations(MappedStatement statement) throws ClassNotFoundException {
-        final String id = statement.getId();
-        Set<String> set = METHOD_PARAM_ANNOTATIONS_MAP.get(id);
-        if (set != null) {
-            return set;
-        }
-        set = new HashSet<>();
-        Method m = getMethodByMappedStatementId(id);
-        if (m == null) {
-            return set;
-        }
-        final Annotation[][] paramAnnotations = m.getParameterAnnotations();
-        // get names from @CryptField annotations
-        for (Annotation[] paramAnnotation : paramAnnotations) {
-            for (Annotation annotation : paramAnnotation) {
-                if (annotation instanceof CryptField) {
-                    CryptField cryptField = (CryptField) annotation;
-                    // 如果允许加密
-                    if (cryptField.encrypt()) {
-                        set.add(cryptField.value());
-                    }
-                    break;
-                }
-            }
-        }
-
-        Set<String> oldSet = METHOD_PARAM_ANNOTATIONS_MAP.putIfAbsent(id, set);
-        if (oldSet != null) {
-            set = oldSet;
-        }
-
-        return set;
-    }
-
-    /**
-     * 通过mappedStatementId get Method
-     *
-     * @param id
-     * @return
-     * @throws ClassNotFoundException
-     */
-    private Method getMethodByMappedStatementId(String id) throws ClassNotFoundException {
-        Method m = null;
-        final Class clazz = Class.forName(id.substring(0, id.lastIndexOf(MAPPEDSTATEMENT_ID_SEPERATOR)));
-        for (Method method : clazz.getMethods()) {
-            if (method.getName().equals(id.substring(id.lastIndexOf(MAPPEDSTATEMENT_ID_SEPERATOR) + 1))) {
-                m = method;
-                break;
-            }
-        }
-
-        return m;
-    }
-
-    /**
-     * 判断是否需要加解密
-     *
-     * @param o
-     * @return
-     */
-    private boolean isNotCrypt(Object o) {
-        return o == null || o instanceof Double || o instanceof Integer || o instanceof Long || o instanceof Boolean;
-    }
-
-    /**
-     * String 加密
-     *
-     * @param str
-     * @return
-     * @throws Exception
-     */
-    private String stringEncrypt(String str) throws Exception {
-        return stringEncrypt(null, str, null, null);
-    }
-
-    /**
-     * String 加密
-     *
-     * @param str
-     * @param set
-     * @return
-     * @throws Exception
-     */
-    private String stringEncrypt(String str, Set<String> set) throws Exception {
-        return stringEncrypt(null, str, set, true);
-    }
-
-    /**
-     * String 加密
-     *
-     * @param name
-     * @param str
-     * @param set
-     * @return
-     * @throws Exception
-     */
-    private String stringEncrypt(String name, String str, Set<String> set) throws Exception {
-        return stringEncrypt(name, str, set, false);
-    }
-
-    /**
-     * String 加密
-     *
-     * @param name
-     * @param str
-     * @param set
-     * @param isSingle
-     * @return
-     * @throws Exception
-     */
-    private String stringEncrypt(String name, String str, Set<String> set, Boolean isSingle) throws Exception {
-        if (StringUtils.isBlank(str)) {
-            return str;
-        }
-        if (isSingle == null) {
-            //todo 加密实现
-            str = CryptUtil.encrypt_char(str);
-            return str;
-        }
-        if (isSingle && set != null && !set.isEmpty()) {
-            //todo 加密实现
-            str = CryptUtil.encrypt_char(str);
-            return str;
-        }
-        if (!isSingle && set != null && !set.isEmpty() && set.contains(name)) {
-            //todo 加密实现
-            str = CryptUtil.encrypt_char(str);
-            return str;
-        }
-
-        return str;
-    }
-
-    /**
-     * String 解密
-     *
-     * @param str
-     * @return
-     */
-    private String stringDecrypt(String str) {
-        if (StringUtils.isBlank(str)) {
-            return str;
-        }
-//        String[] array = str.split("\\|");
-//        if (array.length < 2) {
+package com.diagbot.aop;//package com.diagbot.aop;
+//
+//import com.diagbot.annotation.CryptField;
+//import com.diagbot.util.CryptUtil;
+//import org.apache.commons.lang3.StringUtils;
+//import org.apache.ibatis.binding.MapperMethod;
+//import org.apache.ibatis.executor.Executor;
+//import org.apache.ibatis.mapping.MappedStatement;
+//import org.apache.ibatis.plugin.Interceptor;
+//import org.apache.ibatis.plugin.Intercepts;
+//import org.apache.ibatis.plugin.Invocation;
+//import org.apache.ibatis.plugin.Plugin;
+//import org.apache.ibatis.plugin.Signature;
+//import org.apache.ibatis.session.ResultHandler;
+//import org.apache.ibatis.session.RowBounds;
+//import org.apache.ibatis.session.defaults.DefaultSqlSession;
+//import org.springframework.stereotype.Component;
+//
+//import java.lang.annotation.Annotation;
+//import java.lang.reflect.Field;
+//import java.lang.reflect.Method;
+//import java.util.HashSet;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.Properties;
+//import java.util.Set;
+//import java.util.concurrent.ConcurrentHashMap;
+//
+///**
+// * @Description: 数据库加解密
+// * @author: gaodm
+// * @time: 2019/12/30 18:38
+// */
+//@Intercepts({
+//        @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }),
+//        @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class })
+//})
+////@Component
+//public class CryptInterceptor implements Interceptor {
+//
+//    private static final String PARAM = "param";
+//
+//    private static final String PARAM_TYPE_LIST = "list";
+//
+//    private static final String PARAM_TYPE_COLLECTION = "collection";
+//
+//    private static final String MAPPEDSTATEMENT_ID_SEPERATOR = ".";
+//
+//    /**
+//     * 适用于加密判断
+//     */
+//    private static final ConcurrentHashMap<String, Set<String>> METHOD_PARAM_ANNOTATIONS_MAP = new ConcurrentHashMap<>();
+//    /**
+//     * 适用于解密判断
+//     */
+//    private static final ConcurrentHashMap<String, Boolean> METHOD_ANNOTATIONS_MAP = new ConcurrentHashMap<>();
+//
+//    public CryptInterceptor() {
+//
+//    }
+//
+//    @Override
+//    public Object intercept(Invocation invocation) throws Throwable {
+//        Object[] args = invocation.getArgs();
+//        // 入参
+//        Object parameter = args[1];
+//        MappedStatement statement = (MappedStatement) args[0];
+//        // 判断是否需要解析
+//        if (!isNotCrypt(parameter)) {
+//            // 单参数 string
+//            if (parameter instanceof String) {
+//                args[1] = stringEncrypt((String) parameter, getParameterAnnotations(statement));
+//                // 单参数 list
+//            } else if (parameter instanceof DefaultSqlSession.StrictMap) {
+//                DefaultSqlSession.StrictMap<Object> strictMap = (DefaultSqlSession.StrictMap<Object>) parameter;
+//                for (Map.Entry<String, Object> entry : strictMap.entrySet()) {
+//                    if (entry.getKey().contains(PARAM_TYPE_COLLECTION)) {
+//                        continue;
+//                    }
+//                    if (entry.getKey().contains(PARAM_TYPE_LIST)) {
+//                        Set<String> set = getParameterAnnotations(statement);
+//                        listEncrypt((List) entry.getValue(), !set.isEmpty());
+//                    }
+//                }
+//                // 多参数
+//            } else if (parameter instanceof MapperMethod.ParamMap) {
+//                MapperMethod.ParamMap<Object> paramMap = (MapperMethod.ParamMap<Object>) parameter;
+//                Set<String> set = getParameterAnnotations(statement);
+//                boolean setEmpty = set.isEmpty();
+//                // 解析每一个参数
+//                for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
+//                    // 判断不需要解析的类型 不解析map
+//                    if (isNotCrypt(entry.getValue()) || entry.getValue() instanceof Map || entry.getKey().contains(PARAM)) {
+//                        continue;
+//                    }
+//                    // 如果string
+//                    if (entry.getValue() instanceof String) {
+//                        entry.setValue(stringEncrypt(entry.getKey(), (String) entry.getValue(), set));
+//                        continue;
+//                    }
+//                    boolean isSetValue = !setEmpty && set.contains(entry.getKey());
+//                    // 如果 list
+//                    if (entry.getValue() instanceof List) {
+//                        listEncrypt((List) entry.getValue(), isSetValue);
+//                        continue;
+//                    }
+//                    beanEncrypt(entry.getValue());
+//                }
+//                // bean
+//            } else {
+//                beanEncrypt(parameter);
+//            }
+//        }
+//
+//        // 获得出参
+//        Object returnValue = invocation.proceed();
+//
+//        // 出参解密
+//        if (isNotCrypt(returnValue)) {
+//            return returnValue;
+//        }
+//        Boolean bo = getMethodAnnotations(statement);
+//        if (returnValue instanceof String && bo) {
+//            return stringDecrypt((String) returnValue);
+//        }
+//        if (returnValue instanceof List) {
+//            listDecrypt((List) returnValue, bo);
+//            return returnValue;
+//        }
+//
+//        return returnValue;
+//    }
+//
+//    @Override
+//    public Object plugin(Object target) {
+//        return Plugin.wrap(target, this);
+//    }
+//
+//    @Override
+//    public void setProperties(Properties properties) {
+//
+//    }
+//
+//    /**
+//     * 获取 方法上的注解
+//     *
+//     * @param statement
+//     * @return
+//     * @throws ClassNotFoundException
+//     */
+//    private Boolean getMethodAnnotations(MappedStatement statement) throws ClassNotFoundException {
+//        final String id = statement.getId();
+//        Boolean bo = METHOD_ANNOTATIONS_MAP.get(id);
+//        if (bo != null) {
+//            return bo;
+//        }
+//        Method m = getMethodByMappedStatementId(id);
+//        if (m == null) {
+//            return Boolean.FALSE;
+//        }
+//        final CryptField cryptField = m.getAnnotation(CryptField.class);
+//        // 如果允许解密
+//        if (cryptField != null && cryptField.decrypt()) {
+//            bo = Boolean.TRUE;
+//        } else {
+//            bo = Boolean.FALSE;
+//        }
+//        Boolean bo1 = METHOD_ANNOTATIONS_MAP.putIfAbsent(id, bo);
+//        if (bo1 != null) {
+//            bo = bo1;
+//        }
+//
+//        return bo;
+//    }
+//
+//    /**
+//     * 获取 方法参数上的注解
+//     *
+//     * @param statement
+//     * @return
+//     * @throws ClassNotFoundException
+//     */
+//    private Set<String> getParameterAnnotations(MappedStatement statement) throws ClassNotFoundException {
+//        final String id = statement.getId();
+//        Set<String> set = METHOD_PARAM_ANNOTATIONS_MAP.get(id);
+//        if (set != null) {
+//            return set;
+//        }
+//        set = new HashSet<>();
+//        Method m = getMethodByMappedStatementId(id);
+//        if (m == null) {
+//            return set;
+//        }
+//        final Annotation[][] paramAnnotations = m.getParameterAnnotations();
+//        // get names from @CryptField annotations
+//        for (Annotation[] paramAnnotation : paramAnnotations) {
+//            for (Annotation annotation : paramAnnotation) {
+//                if (annotation instanceof CryptField) {
+//                    CryptField cryptField = (CryptField) annotation;
+//                    // 如果允许加密
+//                    if (cryptField.encrypt()) {
+//                        set.add(cryptField.value());
+//                    }
+//                    break;
+//                }
+//            }
+//        }
+//
+//        Set<String> oldSet = METHOD_PARAM_ANNOTATIONS_MAP.putIfAbsent(id, set);
+//        if (oldSet != null) {
+//            set = oldSet;
+//        }
+//
+//        return set;
+//    }
+//
+//    /**
+//     * 通过mappedStatementId get Method
+//     *
+//     * @param id
+//     * @return
+//     * @throws ClassNotFoundException
+//     */
+//    private Method getMethodByMappedStatementId(String id) throws ClassNotFoundException {
+//        Method m = null;
+//        final Class clazz = Class.forName(id.substring(0, id.lastIndexOf(MAPPEDSTATEMENT_ID_SEPERATOR)));
+//        for (Method method : clazz.getMethods()) {
+//            if (method.getName().equals(id.substring(id.lastIndexOf(MAPPEDSTATEMENT_ID_SEPERATOR) + 1))) {
+//                m = method;
+//                break;
+//            }
+//        }
+//
+//        return m;
+//    }
+//
+//    /**
+//     * 判断是否需要加解密
+//     *
+//     * @param o
+//     * @return
+//     */
+//    private boolean isNotCrypt(Object o) {
+//        return o == null || o instanceof Double || o instanceof Integer || o instanceof Long || o instanceof Boolean;
+//    }
+//
+//    /**
+//     * String 加密
+//     *
+//     * @param str
+//     * @return
+//     * @throws Exception
+//     */
+//    private String stringEncrypt(String str) throws Exception {
+//        return stringEncrypt(null, str, null, null);
+//    }
+//
+//    /**
+//     * String 加密
+//     *
+//     * @param str
+//     * @param set
+//     * @return
+//     * @throws Exception
+//     */
+//    private String stringEncrypt(String str, Set<String> set) throws Exception {
+//        return stringEncrypt(null, str, set, true);
+//    }
+//
+//    /**
+//     * String 加密
+//     *
+//     * @param name
+//     * @param str
+//     * @param set
+//     * @return
+//     * @throws Exception
+//     */
+//    private String stringEncrypt(String name, String str, Set<String> set) throws Exception {
+//        return stringEncrypt(name, str, set, false);
+//    }
+//
+//    /**
+//     * String 加密
+//     *
+//     * @param name
+//     * @param str
+//     * @param set
+//     * @param isSingle
+//     * @return
+//     * @throws Exception
+//     */
+//    private String stringEncrypt(String name, String str, Set<String> set, Boolean isSingle) throws Exception {
+//        if (StringUtils.isBlank(str)) {
 //            return str;
 //        }
-        //todo 解密实现
-        str = CryptUtil.decrypt_char(str);
-
-        return str;
-    }
-
-    /**
-     * list 加密
-     *
-     * @param list
-     * @param bo
-     * @return
-     * @throws Exception
-     */
-    private List listEncrypt(List list, Boolean bo) throws Exception {
-        for (int i = 0; i < list.size(); i++) {
-            Object listValue = list.get(i);
-            // 判断不需要解析的类型
-            if (isNotCrypt(listValue) || listValue instanceof Map) {
-                break;
-            }
-            if (listValue instanceof String && bo) {
-                list.set(i, stringEncrypt((String) listValue));
-                continue;
-            }
-            beanEncrypt(listValue);
-        }
-
-        return list;
-    }
-
-    /**
-     * list 解密
-     *
-     * @param list
-     * @param bo
-     * @return
-     * @throws Exception
-     */
-    private List listDecrypt(List list, Boolean bo) throws Exception {
-        for (int i = 0; i < list.size(); i++) {
-            Object listValue = list.get(i);
-            // 判断不需要解析的类型 获得
-            if (isNotCrypt(listValue) || listValue instanceof Map) {
-                break;
-            }
-            if (listValue instanceof String && bo) {
-                list.set(i, stringDecrypt((String) listValue));
-                continue;
-            }
-            beanDecrypt(listValue);
-        }
-
-        return list;
-    }
-
-    /**
-     * bean 加密
-     *
-     * @param val
-     * @throws Exception
-     */
-    private void beanEncrypt(Object val) throws Exception {
-        Class objClazz = val.getClass();
-        Field[] objFields = objClazz.getDeclaredFields();
-        for (Field field : objFields) {
-            CryptField cryptField = field.getAnnotation(CryptField.class);
-            if (cryptField != null && cryptField.encrypt()) {
-                field.setAccessible(true);
-                Object fieldValue = field.get(val);
-                if (fieldValue == null) {
-                    continue;
-                }
-                if (field.getType().equals(String.class)) {
-                    field.set(val, stringEncrypt((String) fieldValue));
-                    continue;
-                }
-                if (field.getType().equals(List.class)) {
-                    field.set(val, listEncrypt((List) fieldValue, Boolean.TRUE));
-                    continue;
-                }
-            }
-        }
-    }
-
-    /**
-     * bean 解密
-     *
-     * @param val
-     * @throws Exception
-     */
-    private void beanDecrypt(Object val) throws Exception {
-        Class objClazz = val.getClass();
-        Field[] objFields = objClazz.getDeclaredFields();
-        for (Field field : objFields) {
-            CryptField cryptField = field.getAnnotation(CryptField.class);
-            if (cryptField != null && cryptField.decrypt()) {
-                field.setAccessible(true);
-                Object fieldValue = field.get(val);
-                if (fieldValue == null) {
-                    continue;
-                }
-                if (field.getType().equals(String.class)) {
-                    field.set(val, stringDecrypt((String) fieldValue));
-                    continue;
-                }
-                if (field.getType().equals(List.class)) {
-                    field.set(val, listDecrypt((List) fieldValue, Boolean.TRUE));
-                    continue;
-                }
-            }
-        }
-    }
-}
+//        if (isSingle == null) {
+//            //todo 加密实现
+//            str = CryptUtil.encrypt_char(str);
+//            return str;
+//        }
+//        if (isSingle && set != null && !set.isEmpty()) {
+//            //todo 加密实现
+//            str = CryptUtil.encrypt_char(str);
+//            return str;
+//        }
+//        if (!isSingle && set != null && !set.isEmpty() && set.contains(name)) {
+//            //todo 加密实现
+//            str = CryptUtil.encrypt_char(str);
+//            return str;
+//        }
+//
+//        return str;
+//    }
+//
+//    /**
+//     * String 解密
+//     *
+//     * @param str
+//     * @return
+//     */
+//    private String stringDecrypt(String str) {
+//        if (StringUtils.isBlank(str)) {
+//            return str;
+//        }
+////        String[] array = str.split("\\|");
+////        if (array.length < 2) {
+////            return str;
+////        }
+//        //todo 解密实现
+//        str = CryptUtil.decrypt_char(str);
+//
+//        return str;
+//    }
+//
+//    /**
+//     * list 加密
+//     *
+//     * @param list
+//     * @param bo
+//     * @return
+//     * @throws Exception
+//     */
+//    private List listEncrypt(List list, Boolean bo) throws Exception {
+//        for (int i = 0; i < list.size(); i++) {
+//            Object listValue = list.get(i);
+//            // 判断不需要解析的类型
+//            if (isNotCrypt(listValue) || listValue instanceof Map) {
+//                break;
+//            }
+//            if (listValue instanceof String && bo) {
+//                list.set(i, stringEncrypt((String) listValue));
+//                continue;
+//            }
+//            beanEncrypt(listValue);
+//        }
+//
+//        return list;
+//    }
+//
+//    /**
+//     * list 解密
+//     *
+//     * @param list
+//     * @param bo
+//     * @return
+//     * @throws Exception
+//     */
+//    private List listDecrypt(List list, Boolean bo) throws Exception {
+//        for (int i = 0; i < list.size(); i++) {
+//            Object listValue = list.get(i);
+//            // 判断不需要解析的类型 获得
+//            if (isNotCrypt(listValue) || listValue instanceof Map) {
+//                break;
+//            }
+//            if (listValue instanceof String && bo) {
+//                list.set(i, stringDecrypt((String) listValue));
+//                continue;
+//            }
+//            beanDecrypt(listValue);
+//        }
+//
+//        return list;
+//    }
+//
+//    /**
+//     * bean 加密
+//     *
+//     * @param val
+//     * @throws Exception
+//     */
+//    private void beanEncrypt(Object val) throws Exception {
+//        Class objClazz = val.getClass();
+//        Field[] objFields = objClazz.getDeclaredFields();
+//        for (Field field : objFields) {
+//            CryptField cryptField = field.getAnnotation(CryptField.class);
+//            if (cryptField != null && cryptField.encrypt()) {
+//                field.setAccessible(true);
+//                Object fieldValue = field.get(val);
+//                if (fieldValue == null) {
+//                    continue;
+//                }
+//                if (field.getType().equals(String.class)) {
+//                    field.set(val, stringEncrypt((String) fieldValue));
+//                    continue;
+//                }
+//                if (field.getType().equals(List.class)) {
+//                    field.set(val, listEncrypt((List) fieldValue, Boolean.TRUE));
+//                    continue;
+//                }
+//            }
+//        }
+//    }
+//
+//    /**
+//     * bean 解密
+//     *
+//     * @param val
+//     * @throws Exception
+//     */
+//    private void beanDecrypt(Object val) throws Exception {
+//        Class objClazz = val.getClass();
+//        Field[] objFields = objClazz.getDeclaredFields();
+//        for (Field field : objFields) {
+//            CryptField cryptField = field.getAnnotation(CryptField.class);
+//            if (cryptField != null && cryptField.decrypt()) {
+//                field.setAccessible(true);
+//                Object fieldValue = field.get(val);
+//                if (fieldValue == null) {
+//                    continue;
+//                }
+//                if (field.getType().equals(String.class)) {
+//                    field.set(val, stringDecrypt((String) fieldValue));
+//                    continue;
+//                }
+//                if (field.getType().equals(List.class)) {
+//                    field.set(val, listDecrypt((List) fieldValue, Boolean.TRUE));
+//                    continue;
+//                }
+//            }
+//        }
+//    }
+//}