这篇文章主要介绍了SpringBoot通过自定义classloader加密class文件,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
背景
最近针对公司框架进行关键业务代码进行加密处理,防止通过jd-gui等反编译工具能够轻松还原工程代码,相关混淆方案配置使用比较复杂且针对springboot项目问题较多,所以针对class文件加密再通过自定义的classloder进行解密加载,此方案并不是绝对安全,只是加大反编译的困难程度,防君子不防小人,整体加密保护流程图如下图所示
使用自定义maven插件对编译后指定的class文件进行加密,加密后的class文件拷贝到指定路径,这里是保存到resource/coreclass下,删除源class文件,加密使用的是简单的DES对称加密
@Parameter(name = "protectClassNames", defaultValue = "")
private List<String> protectClassNames;
@Parameter(name = "noCompileClassNames", defaultValue = "")
private List<String> noCompileClassNames;
private List<String> protectClassNameList = new ArrayList<>();
private void protectCore(File root) throws IOException {
if (root.isDirectory()) {
for (File file : root.listFiles()) {
protectCore(file);
}
}
String className = root.getName().replace(".class", "");
if (root.getName().endsWith(".class")) {
//class筛选
boolean flag = false;
if (protectClassNames!=null && protectClassNames.size()>0) {
for (String item : protectClassNames) {
if (className.equals(item)) {
flag = true;
}
}
}
if(noCompileClassNames.contains(className)){
boolean deleteResult = root.delete();
if(!deleteResult){
System.gc();
deleteResult = root.delete();
}
System.out.println("【noCompile-deleteResult】:" + deleteResult);
}
if (flag && !protectClassNameList.contains(className)) {
protectClassNameList.add(className);
System.out.println("【protectCore】:" + className);
FileOutputStream fos = null;
try {
final byte[] instrumentBytes = doProtectCore(root);
//加密后的class文件保存路径
String folderPath = output.getAbsolutePath() + "\\" + "classes";
File folder = new File(folderPath);
if(!folder.exists()){
folder.mkdir();
}
folderPath = output.getAbsolutePath() + "\\" + "classes"+ "\\" + "coreclass" ;
folder = new File(folderPath);
if(!folder.exists()){
folder.mkdir();
}
String filePath = output.getAbsolutePat