import com.alibaba.fastjson.JSON;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ClassUtil {
private static final Log logger = LogFactory.getLog(ClassUtil.class);
private static final JavaCompiler compiler;
static {
compiler = ToolProvider.getSystemJavaCompiler();
}
/**
* 获取java文件路径
*
* @param file
* @return
*/
private static String getFilePath(String file) {
int last1 = file.lastIndexOf('/');
int last2 = file.lastIndexOf('\\');
return file.substring(0, Math.max(last1, last2)) + File.separatorChar;
}
/**
* 编译java文件
*
* @param ops 编译参数
* @param files 编译文件
*/
private static void javac(List<String> ops, String... files) {
StandardJavaFileManager manager = null;
try {
manager = compiler.getStandardFileManager(null, null, null);
Iterable<? extends JavaFileObject> it = manager.getJavaFileObjects(files);
JavaCompiler.CompilationTask task = compiler.getTask(null, manager, null, ops, null, it);
task.call();
if (logger.isDebugEnabled()) {
for (String file : files)
logger.debug("Compile Java File:" + file);
}
} catch (Exception e) {
logger.error(e);
} finally {
if (manager != null) {
try {
manager.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 生成java文件
*
* @param file 文件名
* @param source java代码
* @throws Exception
*/
private static void writeJavaFile(String file, String source) throws Exception {
if (logger.isDebugEnabled()) {
logger.debug("Write Java Source Code to:" + file);
}
BufferedWriter bw = null;
try {
File dir = new File(getFilePath(file));
if (!dir.exists())
dir.mkdirs();
bw = new BufferedWriter(new FileWriter(file));
bw.write(source);
bw.flush();
} catch (Exception e) {
throw e;
} finally {
if (bw != null) {
bw.close();
}
}
}
/**
* 加载类
*
* @param name 类名
* @return
*/
private static Class<?> load(String name) {
Class<?> cls = null;
ClassLoader classLoader = null;
try {
classLoader = ClassUtil.class.getClassLoader();
cls = classLoader.loadClass(name);
if (logger.isDebugEnabled()) {
logger.debug("Load Class[" + name + "] by " + classLoader);
}
} catch (Exception e) {
logger.error(e);
}
return cls;
}
/**
* 编译代码并加载类
*
* @param filePath java代码路径
* @param source java代码
* @param clsName 类名
* @param ops 编译参数
* @return
*/
public static Class<?> loadClass(String filePath, String source, String clsName, List<String> ops) {
try {
writeJavaFile(filePath, source);
javac(ops, filePath);
return load(clsName);
} catch (Exception e) {
logger.error(e);
}
return null;
}
/**
* 调用类方法
*
* @param cls 类
* @param methodName 方法名
* @param paramsCls 方法参数类型
* @param params 方法参数
* @return
*/
public static Object invoke(Class<?> cls, String methodName, Class<?>[] paramsCls, Object[] params) {
Object result = null;
try {
Method method = cls.getDeclaredMethod(methodName, paramsCls);
Object obj = cls.newInstance();
result = method.invoke(obj, params);
} catch (Exception e) {
logger.error(e);
}
return result;
}
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
sb.append("package antu.gxpt.util.encry;\n" +
"\n" +
"import com.alibaba.fastjson.JSON;\n" +
"import com.alibaba.fastjson.JSONObject;\n" +
"\n" +
"import javax.crypto.*;\n" +
"import javax.crypto.spec.DESKeySpec;\n" +
"import java.security.InvalidKeyException;\n" +
"import java.security.NoSuchAlgorithmException;\n" +
"import java.security.spec.InvalidKeySpecException;\n" +
"\n" +
"/**\n" +
" * @author big_song\n" +
" * @date 2022/6/15 14:59\n" +
" * @desc\n" +
" */\n" +
"public class TestEncty {\n" +
" private static final String DES_ALGORITHM = \"DES\";\n" +
"\n" +
" public static void main(String[] args) {\n" +
" try {\n" +
" String encryption = encryption(\"{\\n\" + \"\\t\\\"MsgHeader\\\": {\\n\" + \"\\t\\t\\\"TrnCode\\\": \\\"BDC.9001.001.01\\\",\\n\" + \"\\t\\t\\\"RefId\\\": \\\"20170901AA000001\\\",\\n\" + \"\\t\\t\\\"ReqRefId\\\": \\\"\\\",\\n\" + \"\\t\\t\\\"Token\\\": \\\"\\\",\\n\" + \"\\t\\t\\\"Remark\\\": \\\"\\\"\\n\" + \"\\t},\\n\" + \"\\t\\\"MsgBody\\\": {\\n\" + \"\\t\\t\\\"LoginName\\\": \\\"admin\\\",\\n\" + \"\\t\\t\\\"PassWord\\\": \\\"123456\\\"\\n\" + \"\\t}\\n\" + \"}\", \"u9eGtLIa6e1Ne2iyutOk\");\n" +
" System.out.println(encryption);\n" +
" System.out.println(\"============================\");\n" +
" JSONObject jsonObject = new JSONObject();\n" +
" jsonObject.put(\"content\", encryption);\n" +
" jsonObject.put(\"key\", \"u9eGtLIa6e1Ne2iyutOk\");\n" +
" String decryption = decryption(jsonObject.toString());\n" +
" System.out.println(decryption);\n" +
" } catch (Exception e) {\n" +
" throw new RuntimeException(e);\n" +
" }\n" +
" }\n" +
"\n" +
" /**\n" +
" * DES加密\n" +
" *\n" +
" * @param plainData 原始字符串\n" +
" * @param secretKey 加密密钥\n" +
" * @return 加密后的字符串\n" +
" * @throws Exception\n" +
" */\n" +
" public static String encryption(String plainData, String secretKey) throws Exception {\n" +
"\n" +
" Cipher cipher = null;\n" +
" try {\n" +
" cipher = Cipher.getInstance(DES_ALGORITHM);\n" +
" cipher.init(Cipher.ENCRYPT_MODE, generateKey(secretKey));\n" +
"\n" +
" } catch (NoSuchAlgorithmException e) {\n" +
" e.printStackTrace();\n" +
" } catch (NoSuchPaddingException e) {\n" +
" e.printStackTrace();\n" +
" } catch (InvalidKeyException e) {\n" +
"\n" +
" }\n" +
"\n" +
" try {\n" +
" // 为了防止解密时报javax.crypto.IllegalBlockSizeException: Input length must\n" +
" // be multiple of 8 when decrypting with padded cipher异常,\n" +
" // 不能把加密后的字节数组直接转换成字符串\n" +
" byte[] buf = cipher.doFinal(plainData.getBytes());\n" +
" return Base64Util.encryptBASE64(buf);\n" +
" } catch (IllegalBlockSizeException e) {\n" +
" e.printStackTrace();\n" +
" throw new Exception(\"IllegalBlockSizeException\", e);\n" +
" } catch (BadPaddingException e) {\n" +
" e.printStackTrace();\n" +
" throw new Exception(\"BadPaddingException\", e);\n" +
" }\n" +
"\n" +
" }\n" +
"\n" +
"\n" +
" /**\n" +
" * DES解密\n" +
" *\n" +
" * @return 原始字符串\n" +
" * @throws Exception\n" +
" */\n" +
" public static String decryption(String params) throws Exception {\n" +
" JSONObject jsonObject = JSON.parseObject(params);\n" +
" // 密码字符串\n" +
" String secretData = jsonObject.getString(\"content\");\n" +
" // 解密密钥\n" +
" String secretKey = jsonObject.getString(\"key\");\n" +
" Cipher cipher = null;\n" +
" try {\n" +
" cipher = Cipher.getInstance(DES_ALGORITHM);\n" +
" cipher.init(Cipher.DECRYPT_MODE, generateKey(secretKey));\n" +
"\n" +
" } catch (NoSuchAlgorithmException e) {\n" +
" e.printStackTrace();\n" +
" throw new Exception(\"NoSuchAlgorithmException\", e);\n" +
" } catch (NoSuchPaddingException e) {\n" +
" e.printStackTrace();\n" +
" throw new Exception(\"NoSuchPaddingException\", e);\n" +
" } catch (InvalidKeyException e) {\n" +
" e.printStackTrace();\n" +
" throw new Exception(\"InvalidKeyException\", e);\n" +
" }\n" +
"\n" +
" try {\n" +
" byte[] buf = cipher.doFinal(Base64Util.decryBASE64(secretData));\n" +
" return new String(buf);\n" +
"\n" +
" } catch (IllegalBlockSizeException e) {\n" +
" e.printStackTrace();\n" +
" throw new Exception(\"IllegalBlockSizeException\", e);\n" +
" } catch (BadPaddingException e) {\n" +
" e.printStackTrace();\n" +
" throw new Exception(\"BadPaddingException\", e);\n" +
" }\n" +
" }\n" +
"\n" +
" /**\n" +
" * 获得秘密密钥\n" +
" *\n" +
" * @param secretKey\n" +
" * @return\n" +
" * @throws NoSuchAlgorithmException\n" +
" * @throws InvalidKeySpecException\n" +
" * @throws InvalidKeyException\n" +
" */\n" +
" private static SecretKey generateKey(String secretKey)\n" +
" throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {\n" +
" SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);\n" +
" DESKeySpec keySpec = new DESKeySpec(secretKey.getBytes());\n" +
" keyFactory.generateSecret(keySpec);\n" +
" return keyFactory.generateSecret(keySpec);\n" +
" }\n" +
"}\n");
//设置编译参数
ArrayList<String> ops = new ArrayList<>();
ops.add("-Xlint:unchecked");
//编译代码,返回class
Class<?> cls = ClassUtil.loadClass("/antu/gxpt/util/encry//TestEncty.java", sb.toString(), "antu.gxpt.util.encry.TestEncty", ops);
//准备测试数据
Map<String, String> data = new HashMap<>();
data.put("content", "FcZPxffiRxP4SOBbgmrRS7tXjobATegwfJETTA+xbmmJxEHf0zssu1H+BlMKpqYIuVAghbg/VDRo\n" +
"cZeppZijFTJJJcYn/wJEYD8isvuPSgaDNF70AGVCFjZv/YR3QWkFF9SRL7tk5ILv1OeLnzdB4DEM\n" +
"VwSg8nygUwLmuR5K+/U0jSjHYWWByLSGDrpeUl9h1/IOIlx5OdG7k3abiAMGxpPf/nAnfrsnh3vA\n" +
"tEKI0Y5X6XKW64qei+3vmXo5/sO5Xdpazc72qT0=");
data.put("key", "u9eGtLIa6e1Ne2iyutOk");
//执行测试方法
Object result = ClassUtil.invoke(cls, "decryption", new Class[]{String.class}, new Object[]{JSON.toJSONString(data)});
//输出结果
System.out.println(data);
System.out.println("(30*f1+20*f2+50*f3)/100 = " + result);
}
}