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