From e29546af6fcc89c64b17cee6de01ce2a963b33f4 Mon Sep 17 00:00:00 2001
From: chenjiahe <763432473@qq.com>
Date: 星期五, 07 一月 2022 19:08:37 +0800
Subject: [PATCH] AES

---
 src/main/java/com/hx/common/annotations/MysqlHexAes.java           |   20 +++
 src/main/java/com/hx/springbean/VariableAesKey.java                |  196 ++++++++++++++++++++++++++++++++
 src/main/java/com/hx/mybatis/handler/aes/GenericStringHandler.java |   55 +++++++++
 src/main/java/com/hx/springbean/ConstantBean.java                  |   34 +++++
 4 files changed, 305 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/hx/common/annotations/MysqlHexAes.java b/src/main/java/com/hx/common/annotations/MysqlHexAes.java
new file mode 100644
index 0000000..a143106
--- /dev/null
+++ b/src/main/java/com/hx/common/annotations/MysqlHexAes.java
@@ -0,0 +1,20 @@
+package com.hx.common.annotations;
+
+import java.lang.annotation.*;
+
+/**
+ * 鎸囧畾mysql鐨凙ES鍔犲瘑瀛楁
+ * @author CJH
+ */
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface MysqlHexAes {
+    /**绉橀挜瀛楁*/
+    String aesKeyField() default "";
+    /**绉橀挜*/
+    String aesKey();
+    /**鏌ヨ瑙e瘑*/
+    boolean selectDec() default false;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/hx/mybatis/handler/aes/GenericStringHandler.java b/src/main/java/com/hx/mybatis/handler/aes/GenericStringHandler.java
new file mode 100644
index 0000000..4701535
--- /dev/null
+++ b/src/main/java/com/hx/mybatis/handler/aes/GenericStringHandler.java
@@ -0,0 +1,55 @@
+package com.hx.mybatis.handler.aes;
+
+import com.hx.util.mysql.aes.MysqlHexAes;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * @author CJH
+ * @Date 2021-01-02
+ * // @MappedTypes娉ㄨВ涓殑绫讳唬琛ㄦ杞崲鍣ㄥ彲浠ヨ嚜鍔ㄨ浆鎹负鐨刯ava瀵硅薄锛孈MappedJdbcTypes娉ㄨВ涓缃殑鏄搴旂殑jdbctype锛宮ysql鐨刯son瀵硅薄瀵瑰簲鐨刯dbctype涓篤ARCHAR銆�
+ */
+@MappedTypes(value = {String.class})
+@MappedJdbcTypes(value = {JdbcType.VARCHAR}, includeNullJdbcType = true)
+public class GenericStringHandler extends BaseTypeHandler<String> {
+
+    public GenericStringHandler() {
+    }
+
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
+        ps.setString(i, parameter);
+    }
+
+    @Override
+    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        String data = rs.getString(columnName);
+        if(data != null && data.length()%32==0 && MysqlHexAes.isHexStrValid(data)){
+            try{
+                data = MysqlHexAes.decryptData(data,"123456",null);
+            }catch (Exception e){
+                //e.printStackTrace();
+            }
+        }
+        return data;
+    }
+
+    @Override
+    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        return rs.getString(columnIndex);
+    }
+
+    @Override
+    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        return cs.getString(columnIndex);
+    }
+
+}
+
diff --git a/src/main/java/com/hx/springbean/ConstantBean.java b/src/main/java/com/hx/springbean/ConstantBean.java
new file mode 100644
index 0000000..e36d5cd
--- /dev/null
+++ b/src/main/java/com/hx/springbean/ConstantBean.java
@@ -0,0 +1,34 @@
+package com.hx.springbean;
+
+import com.hx.common.annotations.MysqlHexAes;
+import com.hx.util.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.*;
+
+/**
+ * 閫氱敤甯搁噺闆嗕腑钀�
+ * @author CJH
+ */
+@Component
+public class ConstantBean {
+
+    /**鑾峰彇AES绉橀挜鐨勯厤缃紙浠庝粈涔堝寘鑾峰彇鍒帮級*/
+    @Value("${mysql.hxe.aex.find.packs:null}")
+    private String packPath;
+
+    public String getPackPath() {
+        return packPath;
+    }
+
+    public void setPackPath(String packPath) {
+        this.packPath = packPath;
+    }
+}
diff --git a/src/main/java/com/hx/springbean/VariableAesKey.java b/src/main/java/com/hx/springbean/VariableAesKey.java
new file mode 100644
index 0000000..f9168c0
--- /dev/null
+++ b/src/main/java/com/hx/springbean/VariableAesKey.java
@@ -0,0 +1,196 @@
+package com.hx.springbean;
+
+import com.hx.common.annotations.MysqlHexAes;
+import com.hx.util.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.*;
+
+/**
+ * 鑾峰彇鎸囧畾鍖呴噷闈㈢殑AES绉橀挜
+ */
+@Component
+public class VariableAesKey {
+
+    @Resource
+    private ConstantBean constantBean;
+
+    /**瀛樺偍AES鐨勭閽�*/
+    public static Map<String,String> aesKeys = new HashMap<>();
+
+    /**瀛樺偍AES绉橀挜*/
+    public static void setAesKey(String aesKeyFild,String aesKey){
+        aesKeys.put(aesKeyFild,aesKey);
+    }
+    /**鑾峰彇AES绉橀挜*/
+    public static String getAesKey(String aesKeyFild){
+        return aesKeys.get(aesKeyFild);
+    }
+
+    /**
+     * 椤圭洰鍚姩灏辨墽琛屽悗灏辨墽琛岃鏂规硶
+     */
+    @PostConstruct
+    public void VariableAesKey(){
+        //椤圭洰鍚姩鐨勬椂鍊欏~鍏�
+        System.err.println("鎵弿鑾峰彇AES:" + constantBean.getPackPath());
+        if(StringUtils.noNull(constantBean.getPackPath())){
+            Set<Class<?>> classes = classData(constantBean.getPackPath());
+            for(Class<?> cl:classes){
+                // 鍙栧緱鏈被鐨勫叏閮ㄥ睘鎬�
+                Field[] fields = cl.getDeclaredFields();
+                fields = getPatentFields(fields,cl);
+                for (Field field:fields) {
+                    // 鍒ゆ柇鏂规硶涓槸鍚︽湁鎸囧畾娉ㄨВ绫诲瀷鐨勬敞瑙�
+                    boolean hasAnnotation = field.isAnnotationPresent(MysqlHexAes.class);
+                    if (hasAnnotation) {
+                        // 鏍规嵁娉ㄨВ绫诲瀷杩斿洖鏂规硶鐨勬寚瀹氱被鍨嬫敞瑙�
+                        MysqlHexAes mysqlHexAes = field.getAnnotation(MysqlHexAes.class);
+
+                        String aesKeyField = mysqlHexAes.aesKeyField();
+                        String aesKey = mysqlHexAes.aesKey();
+
+                        if(StringUtils.isEmpty(aesKey)){
+                            throw new RuntimeException("mysql鐨凙ES绉橀挜涓嶈兘涓虹┖:"+field.getName());
+                        }
+                        if(StringUtils.noNull(aesKeyField)){
+                            String key = aesKeys.get(aesKeyField);
+                            if(StringUtils.isEmpty(key)){
+                                aesKeys.put(aesKeyField,aesKey);
+                            }else{
+                                if(!aesKey.equals(key)){
+                                    throw new RuntimeException("瀛楁/瀹氫箟鐨凙ES绉橀挜瀛楁銆�"+field.getName()+"銆戝涓竴鏍凤紝浣嗘槸AES绉橀挜涓嶄竴鏍�");
+                                }
+                            }
+                        }else{
+                            String key = aesKeys.get(field.getName());
+                            if(StringUtils.isEmpty(key)){
+                                aesKeys.put(field.getName(),aesKey);
+                            }else{
+                                if(!aesKey.equals(key)){
+                                    throw new RuntimeException("瀛楁/瀹氫箟鐨凙ES绉橀挜瀛楁銆�"+field.getName()+"銆戝涓竴鏍凤紝浣嗘槸AES绉橀挜涓嶄竴鏍�");
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**鑾峰彇鍖呬笅闈㈢殑鎵�鏈夋枃浠�*/
+    public static Set<Class<?>> classData(String packPath){
+        Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
+        // 鏄惁寰幆杩唬
+        boolean recursive = true;
+        // 鑾峰彇鍖呯殑鍚嶅瓧 骞惰繘琛屾浛鎹�
+        String packageName = packPath;
+        String packageDirName = packageName.replace('.', '/');
+        // 瀹氫箟涓�涓灇涓剧殑闆嗗悎 骞惰繘琛屽惊鐜潵澶勭悊杩欎釜鐩綍涓嬬殑things
+        Enumeration<URL> dirs;
+        try{
+            dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
+            // 寰幆杩唬涓嬪幓
+            while (dirs.hasMoreElements()){
+                // 鑾峰彇涓嬩竴涓厓绱�
+                URL url = dirs.nextElement();
+                // 寰楀埌鍗忚鐨勫悕绉�
+                String protocol = url.getProtocol();
+                // 濡傛灉鏄互鏂囦欢鐨勫舰寮忎繚瀛樺湪鏈嶅姟鍣ㄤ笂
+                if ("file".equals(protocol)) {
+                    // 鑾峰彇鍖呯殑鐗╃悊璺緞
+                    String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
+                    // 浠ユ枃浠剁殑鏂瑰紡鎵弿鏁翠釜鍖呬笅鐨勬枃浠� 骞舵坊鍔犲埌闆嗗悎涓�
+                    findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes);
+                }
+            }
+        }catch (IOException e){
+            e.printStackTrace();
+        }
+        return classes;
+    }
+
+    /**
+     * 浠ユ枃浠剁殑褰㈠紡鏉ヨ幏鍙栧寘涓嬬殑鎵�鏈塁lass
+     *
+     * @param packageName
+     * @param packagePath
+     * @param recursive
+     * @param classes
+     */
+    public static void findAndAddClassesInPackageByFile(
+            String packageName,
+            String packagePath,
+            final boolean recursive,
+            Set<Class<?>> classes){
+        // 鑾峰彇姝ゅ寘鐨勭洰褰� 寤虹珛涓�涓狥ile
+        File dir = new File(packagePath);
+        // 濡傛灉涓嶅瓨鍦ㄦ垨鑰� 涔熶笉鏄洰褰曞氨鐩存帴杩斿洖
+        if (!dir.exists() || !dir.isDirectory()) {
+            // log.warn("鐢ㄦ埛瀹氫箟鍖呭悕 " + packageName + " 涓嬫病鏈変换浣曟枃浠�");
+            return;
+        }
+        // 濡傛灉瀛樺湪 灏辫幏鍙栧寘涓嬬殑鎵�鏈夋枃浠� 鍖呮嫭鐩綍
+        File[] dirfiles = dir.listFiles(new FileFilter(){
+            // 鑷畾涔夎繃婊よ鍒� 濡傛灉鍙互寰幆(鍖呭惈瀛愮洰褰�) 鎴栧垯鏄互.class缁撳熬鐨勬枃浠�(缂栬瘧濂界殑java绫绘枃浠�)
+            @Override
+            public boolean accept(File file){
+                return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));
+            }
+        });
+        // 寰幆鎵�鏈夋枃浠�
+        for (File file : dirfiles){
+            // 濡傛灉鏄洰褰� 鍒欑户缁壂鎻�
+            if (file.isDirectory()) {
+                findAndAddClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, classes);
+            }else{
+                // 濡傛灉鏄痡ava绫绘枃浠� 鍘绘帀鍚庨潰鐨�.class 鍙暀涓嬬被鍚�
+                String className = file.getName().substring(0, file.getName().length() - 6);
+                try{
+                    // 娣诲姞鍒伴泦鍚堜腑鍘�
+                    // classes.add(Class.forName(packageName + '.' +
+                    // className));
+                    // 缁忚繃鍥炲鍚屽鐨勬彁閱掞紝杩欓噷鐢╢orName鏈変竴浜涗笉濂斤紝浼氳Е鍙憇tatic鏂规硶锛屾病鏈変娇鐢╟lassLoader鐨刲oad骞插噣
+                    classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className));
+                }catch (ClassNotFoundException e){
+                    // log.error("娣诲姞鐢ㄦ埛鑷畾涔夎鍥剧被閿欒 鎵句笉鍒版绫荤殑.class鏂囦欢");
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /**
+     * 鑾峰彇鐖剁被鐨勫瓧娈�
+     * @param fields
+     * @param clas
+     * @return
+     */
+    public static Field[] getPatentFields(Field[] fields,Class<?> clas){
+        if (clas.getSuperclass() != null) {
+            Class clsSup = clas.getSuperclass();
+            List<Field> fieldList = new ArrayList<Field>();
+            fieldList.addAll(Arrays.asList(fields));
+            fieldList.addAll(Arrays.asList(clsSup.getDeclaredFields()));
+            fields = new Field[fieldList.size()];
+            int i = 0;
+            for (Object field : fieldList.toArray()) {
+                fields[i] = (Field) field;
+                i++;
+            }
+            fields = getPatentFields(fields,clsSup);
+        }
+        return  fields;
+    }
+
+
+}

--
Gitblit v1.8.0