欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

springboot 使用proguard插件混淆代码  

程序员文章站 2022-05-26 16:09:20
...

项目使用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。