使用ProGuard对SpringBoot工程进行代码混淆

效果展示

在这里插入图片描述

使用步骤

1/3·首先在pom.xml中添加ProGuard的版本属性

 <properties>
	<proguard.version>7.1.1</proguard.version>
	<proguard.maven.plugin.version>2.5.1</proguard.maven.plugin.version>
 </properties>

2/3·最后在POM.xml中配置build标签,添加ProGuard配置

<build>
        <plugins>
            <!--  代码混淆 -->
            <plugin>
                <groupId>com.github.wvengen</groupId>
                <artifactId>proguard-maven-plugin</artifactId>
                <version>${proguard.maven.plugin.version}</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>proguard</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <proguardVersion>${proguard.version}</proguardVersion>
                    <injar>${project.build.finalName}.jar</injar>
                    <outjar>${project.build.finalName}.jar</outjar>
                    <obfuscate>true</obfuscate>
                    <options>
                        <option>-dontshrink</option>
                        <option>-dontoptimize</option>
                        <!-- 此选项将用新的类名替换反射方法调用中的所有字符串。例如,调用Class.forName('className')-->
                        <option>-adaptclassstrings</option>
                        <!-- 此选项将保存所有原始注解等。否则,将从文件中删除所有注解。-->
                        <option>-keepattributes
                            Exceptions,
                            InnerClasses,
                            Signature,
                            Deprecated,
                            SourceFile,
                            LineNumberTable,
                            *Annotation*,
                            EnclosingMethod
                        </option>
                        <!-- 此选项将保存接口中的所有原始名称(不混淆)-->
                        <option>-keepnames interface **</option>
                        <!-- 此选项将将所有原始方法参数-->
                        <option>-keepparameternames</option>
                        <!-- 此选项将保存所有原始类文件(不混淆),一般是混淆领域或者服务包中的文件。-->
                        <option>-keep
                            class x.x.x.Application {
                            public static void main(java.lang.String[]);
                            }
                        </option>
                        <!-- 此选项忽略警告,例如重复的类定义和命名不正确的文件中的类-->
                        <option>-ignorewarnings</option>
                        <!-- 此选项将保存服务包中的所有原始类文件(不进行混淆)-->
                        <!-- <option>-keep class com.waylau.proguard.service { *; }</option>-->
                        <!-- 此选项将保存所有软件包中的所有原始接口文件(不进行混淆)-->
                        <option>-keep interface * extends * { *; }</option>
                        <!-- 此选项将保存所有包中所有类中的所有原始定义的注解-->
                        <option>-keep class com.fasterxml.jackson.** { *; }</option>
                        <option>-keep class org.json.JSONObject.** {** put(java.lang.String,java.util.Map);}</option>
                        <option>-keepclassmembers class * {
                            @org.springframework.context.annotation.Bean *;
                            @org.springframework.beans.factory.annotation.Autowired *;
                            @org.springframework.beans.factory.annotation.Value *;
                            }
                        </option>
                        <option>-dontwarn com.fasterxml.jackson.databind.**</option>
                        <option>-dontwarn com.fasterxml.jackson.**</option>
                    </options>
                    <injarNotExistsSkip>true</injarNotExistsSkip>
                    <libs>
                        <!--在此添加需要的类库-->
                        <!--<lib>${java.home}/lib/rt.jar</lib>-->
                    </libs>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>com.guardsquare</groupId>
                        <artifactId>proguard-base</artifactId>
                        <version>${proguard.version}</version>
                    </dependency>
                </dependencies>
            </plugin>

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                        <configuration>
                            <mainClass>xx.xx.Application</mainClass>
                        </configuration>
                    </execution>
                </executions>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

接着执行mvn package 来编译工程,编译的时候就会自动进行混淆。

3/3·检查
1·运行jar包检查程序是否正常运行;
2·反编译jar包检查是否成功进行代码混淆;

两件事都没问题那就OK了。

遇到的问题

1·.BeanDefinitionStoreException: Failed to parse configuration class [xxx.xx]; nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name ‘a’ for bean class [xx.xx.a.a] conflicts with existing, non-compatible bean definition of same name and class [xx.xx.a]
从错误信息来看,应该是bean 重名冲突。

最简单的解决办法是保留bean的名字不混淆:

keep 'public @org.springframework.stereotype.Component class **'

一定要混淆的话,那么就必须得指定bean的名字:

@Component("myBeanName")

2·第一个问题我采用“指定bean”的方式解决后,又遇到新的问题:Parameter 0 of constructor in xx.x.A required a bean of type ‘xx.xx.B’ that could not be found.
我这里的情况是:A类在不属于被混淆的jar包,而A依赖的B在被混淆的包中,这就导致A使用的B其名字是未混淆的,但在混淆的包中B名字已经变化了,所以提示找不到。
目前的解决办法就是,让被混淆的包中的B保持不变,这样A就能找到B了。

<option>-keep class xx.xx.B { *; }</option>

本方法存在的问题

仅混淆了启动类所在的包,而依赖的包则没能混淆。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值