springboot 使用proguard插件混淆代码
程序员文章站
2022-05-26 16:09:08
...
项目使用springboot开发,打war包部署。
使用maven导入ProGuard的插件,对代码进行混淆。
maven插件配置如下:
<!-- ProGuard混淆插件--> <plugin> <groupId>com.github.wvengen</groupId> <artifactId>proguard-maven-plugin</artifactId> <version>2.2.0</version> <executions> <execution> <!-- 混淆时刻,这里是打包的时候混淆--> <phase>package</phase> <goals> <!-- 使用插件的什么功能,当然是混淆--> <goal>proguard</goal> </goals> </execution> </executions> <configuration> <attach>true</attach> <attachArtifactClassifier>pg</attachArtifactClassifier> <!-- attach 的作用是在 install 与 deploy 时将生成的 pg 文件也安装与部署 --> <options> <!-- 详细配置方式参考 ProGuard 官方文档 --> <!--<option>-dontobfuscate</option>--> <option>-ignorewarnings</option> <!--忽略所有告警--> <!-- 不做收缩(删除注释、未被引用代码)--> <option>-dontshrink</option> <!-- 不做优化(变更代码实现逻辑)--> <option>-dontoptimize</option> <!-- 不路过非公用类文件及成员--> <option>-dontskipnonpubliclibraryclasses</option> <option>-dontskipnonpubliclibraryclassmembers</option> <!--混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代--> <option>-adaptclassstrings</option> <!--不用大小写混合类名机制--> <option>-dontusemixedcaseclassnames</option> <!-- 优化时允许访问并修改有修饰符的类和类的成员 --> <option>-allowaccessmodification</option> <!-- 确定统一的混淆类的成员名称来增加混淆--> <option>-useuniqueclassmembernames</option> <!--<option>-repackageclasses com.web.app.pg</option>--> <!--平行包结构(重构包层次),所有混淆的类放在 pg 包下--> <!-- 以下为 Keep,哪些内容保持不变,因为有一些内容混淆后(a,b,c)导致反射或按类名字符串相关的操作失效 --> <option>-keep class **.package-info</option> <!--保持包注解类--> <option>-keepattributes Signature</option> <!--JAXB NEED,具体原因不明,不加会导致 JAXB 出异常,如果不使用 JAXB 根据需要修改--> <!-- Jaxb requires generics to be available to perform xml parsing and without this option ProGuard was not retaining that information after obfuscation. That was causing the exception above. --> <!-- 需要保持的属性:异常,注解等--> <option>-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod</option> <!--保持源码名与行号(异常时有明确的栈信息),注解(默认会过滤掉所有注解,会影响框架的注解)--> <option>-keep class com.**.common.annotation.** { *;}</option> <option>-keep class com.**.common.controller.** { *;}</option> <option>-keep class com.**.common.aspect.** { *;}</option> <option>-keep class com.**.common.config.** { *;}</option> <option>-keep class com.**.common.task.** { *;}</option> <option>-keep class com.**.activiti.config.** { *;}</option> <option>-keep class com.**.oa.config.** { *;}</option> <option>-keep class com.**.system.config.** { *;}</option> <option>-keep class com.**.**.domain.** { *;}</option> <option>-keep class com.**.**.dao.** { *;}</option> <option>-keepclassmembers class * { @org.springframework.beans.factory.annotation.Autowired *; @org.springframework.beans.factory.annotation.Value *; @org.springframework.stereotype.Service *; @org.springframework.stereotype.Component *; @org.springframework.scheduling.annotation.Scheduled *; } </option> <option>-keep @org.springframework.boot.autoconfigure.SpringBootApplication class * {*;}</option> <!--保持 Bean 类,(由于很多框架会对 Bean 中的内容做反射处理,请根据自己的业务调整) --> </options> <outjar>${project.build.finalName}-pg</outjar> <libs> <lib>${java.home}/lib/rt.jar</lib> <lib>${java.home}/lib/jce.jar</lib> </libs> <injar>classes</injar> </configuration> </plugin>
运行maven -clean,
然后运行maven -package,
在target包下会生成一个classes-pg.jar和项目名.war两个文件,
springboot如何打war包,可参考上篇文章。
问题:
1.由于在混淆后代码a.class,b.class,c.class等方式,会导致springboot注入bean的时候报bean冲突,需要对生成bean策略进行修改,添加类:
/** * sping下代码混淆后,不同包下的bean名相同会报bean冲突 */ public class UniqueNameGenerator extends AnnotationBeanNameGenerator { @Override public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { //全限定类名 String beanName = definition.getBeanClassName(); return beanName; } }
在启动类添加注释:
@ComponentScan(nameGenerator = UniqueNameGenerator.class)
@ComponentScan(nameGenerator = UniqueNameGenerator.class) public class StartApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(StartApplication.class, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { // 注意这里要指向原先用main方法执行的SpringBootStartApplication 启动类 return builder.sources(StartApplication .class); } }
2.打包部署,该配置文件打包出来的war中classes文件仍然为正常代码,需要手动解压,将classes-pg.jar中classes替换进去。
注意:代码中如果包含反射类,不能进行代码混淆。
最后启动tomcat。