使用proguard对maven构建的springboot项目进行混淆方式
作者:dlut-王不留行
文章介绍了如何使用ProGuard对Maven构建的Spring Boot项目进行混淆,并解决混淆后可能遇到的版本兼容性问题和类名冲突问题,主要步骤包括下载高版本的ProGuard、配置POM文件、添加ProGuard配置文件、修改Spring Boot启动文件以避免类名冲突
1,配置混淆的问题
配置混淆的时候可能会报很多版本错,包括但不限于java版本不对,springboot版本不对,log4j版本不对。。。。。
其实只要proguard版本上去了就行,得自己下一个高版本的proguard.jar.
由于proguard混淆貌似不能指定混淆的类名在basePackages下面类名混淆后唯一,不同包名经常有a.class,b.class,c.class之类重复的类名,因此spring容器初始化bean的时候会报错,因为spring不允许不同包下类名一样,我们需要改变spring的bean的命名策略来解决这个问题 (见步骤2.4)
dao和domain层不要混淆
2,配置过程
2.1 首先下载
下载proguard 6.2.2,其他版本也行,那就把pom的配置改一改版本号,然后在和pom同一级的lib下将proguard文件放进去,千万别放在src下,不然等于让这个jar包混淆自己,铁定报错
2.2 maven pom配置中加入以下
<!-- ProGuard混淆插件--> <plugin> <groupId>com.github.wvengen</groupId> <artifactId>proguard-maven-plugin</artifactId> <executions> <execution> <!-- 混淆时刻,这里是打包的时候混淆--> <phase>package</phase> <goals> <!-- 指定使用插件的混淆功能 --> <goal>proguard</goal> </goals> </execution> </executions> <configuration> <proguardVersion>6.2.2</proguardVersion> <!-- 是否将生成的PG文件安装部署--> <attach>true</attach> <!-- 是否混淆--> <obfuscate>true</obfuscate> <!-- 指定生成文件分类 --> <attachArtifactClassifier>pg</attachArtifactClassifier> <proguardInclude>${basedir}/proguard.conf</proguardInclude> <libs> <lib>${java.home}/lib/rt.jar</lib> <lib>${java.home}/lib/jce.jar</lib> <lib>${java.home}/lib/jsse.jar</lib> </libs> <!-- 对什么东西进行加载,这里仅有classes成功,不可能对配置文件及JSP混淆吧--> <injar>classes</injar> <outjar>${project.build.finalName}-pg.jar</outjar> <!-- 输出目录--> <outputDirectory>${project.build.directory}</outputDirectory> </configuration> <dependencies> <dependency> <groupId>net.sf.proguard</groupId> <artifactId>proguard-base</artifactId> <version>6.2.2</version> <scope>system</scope> <systemPath>${basedir}/lib/proguard.jar</systemPath> </dependency> </dependencies> </plugin>
2.3 在pom同级目录下添加proguard.conf文件
# 忽略所有警告,否则有警告的时候混淆会停止 -ignorewarnings # JDK目标版本1.8 -target 1.8 # 不做收缩(删除注释、未被引用代码) -dontshrink # 不做优化(变更代码实现逻辑) -dontoptimize # 不路过非公用类文件及成员 -dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers ## 混淆时不生成大小写混合的类名,默认是可以大小写混合 -dontusemixedcaseclassnames # 优化时允许访问并修改有修饰符的类和类的成员 -allowaccessmodification # 确定统一的混淆类的成员名称来增加混淆 -useuniqueclassmembernames # 不混淆所有包名,本人测试混淆后WEB项目问题实在太多,毕竟Spring配置中有大量固定写法的包名 -keeppackagenames # 不混淆局部变量名 -keepparameternames # 不删除注解 -keepattributes *Annotation* # 不混淆所有特殊的类 LocalVariable*Table, -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,Synthetic,EnclosingMethod # 不混淆所有的set/get方法,毕竟项目中使用的部分第三方框架(例如Shiro)会用到大量的set/get映射 -keepclassmembers public class * {void set*(***);*** get*();} ##对异常、注解信息在runtime予以保留,不然影响springboot启动 -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod ##保留main方法的类及其方法名 -keepclasseswithmembers public class * { public static void main(java.lang.String[]);} ##保留枚举成员及方法 -keepclassmembers enum * { *; } # 不混淆泛型 -keepattributes Signature #!!!!!!!不混淆dao和domain!!!!! -keep class com.dingding.managerplate.system.dao.** {*;} -keep class com.dingding.managerplate.system.domain.** {*;} #可以通过这个配置自己添加混淆字典 #-classobfuscationdictionary ./filename.txt ## 混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代 #-adaptclassstrings # 保持类protected不被混淆 #-keep public class * { public protected <fields>;public protected <methods>; }
2.4 修改springboot的启动文件
让springboot为bean命名时将包名带上,不然会因为混淆后不同包下出现同名类而产生冲突
@SpringBootApplication public class ManagerplateApplication { public static class CustomGenerator implements BeanNameGenerator { @Override public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { return definition.getBeanClassName(); } } public static void main(String[] args) { new SpringApplicationBuilder(ManagerplateApplication.class) .beanNameGenerator(new CustomGenerator()) .run(args); } }
2.5 执行 sudo mvn clean package -DskipTests
(最好加sudo,别问我怎么知道的)
2.6 混淆完成,生成可执行jar包
在target目录下会生成4个文件:
- classes-pg.jar 混淆后的classes文件,里面包含完整的项目结构
- proguard_map.txt 混淆内容的映射
- proguard_seed.txt 参与混淆的类
- 还有一个未混淆的原始jar包
#解压class-pg.jar 和未混淆的jar包 unzip class-pg.jar unzip 未混淆的jar包 #将class-pg.jar解压出的所有内容替换掉 未混淆的jar包/BOOT-INF/classes下的全部文件 #重新打包被替换过的jar包 jar cvfM0 name.jar *
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。