来源:blog.csdn.net/mawei7510/article/details/130828709
一、背景
项目组核心代码模块部署于用户服务器上,直接甩jar包到服务器的方式,极有可能导致数据泄露和代码泄露,为了防止有技术能力的用户反编译我们的程序,采用了proguard和xjar两种方式来混淆和加密jar包。
注:加密技术只是提高别人获取你的代码的门槛,没有绝对安全的加密方式,而安全等级越高,程序开发、运维、部署的成本就越高,所以,合适的加密技术就是最好的。
二、简介
1.ProGuard是一个压缩、优化和混淆Java字节码文件的免费的工具,它可以删除无用的类、字段、方法和属性。可以删除没用的注释,最大限度地优化字节码文件。它还可以使用简短的无意义的名称来重命名已经存在的类、字段、方法和属性。常常用于Android开发用于混淆最终的项目,增加项目被反编译的难度。
2.Xjar
- Spring Boot JAR 安全加密运行工具, 同时支持的原生JAR
- 基于对JAR包内资源的加密以及拓展ClassLoader来构建的一套程序加密启动, 动态解密运行的方案, 避免源码泄露以及反编译.
功能特性
- 无代码侵入, 只需要把编译好的JAR包通过工具加密即可.
- 完全内存解密, 降低源码以及字节码泄露或反编译的风险.
- 支持所有JDK内置加解密算法.
- 可选择需要加解密的字节码或其他资源文件.
- 支持Maven插件, 加密更加便捷.
- 动态生成Go启动器, 保护密码不泄露.
3.ClassFinal是一款Java class文件安全加密工具,支持直接加密jar包或war包,无需修改任何项目代码,兼容spring-framework,可避免源码泄漏或字节码被反编译,
功能特性
- 无需修改原项目代码,只要把编译好的jar/war包用本工具加密即可。
- 运行加密项目时,无需求修改tomcat,spring等源代码。
- 支持普通jar包、springboot jar包以及普通java web项目编译的war包。
- 支持spring framework、swagger等需要在启动过程中扫描注解或生成字节码的框架。
- 支持maven插件,添加插件后在打包过程中自动加密。
- 支持加密WEB-INF/lib或BOOT-INF/lib下的依赖jar包。
三、预研了classfinal
classfinal其实也可以起到代码加密的效果,功能也很强大,被classfinal加密过后的jar包,反编译了以后,方法返回值会return null或者0,方法内部会自动去掉。并且用classfinal加密过后的jar包启动方式需要用javaagnet启动。而相比较xjar,反编译以后,反编译后,直接显示Internal Error.
1.module pom文件引入
<plugin><groupId>net.roseboy</groupId><artifactId>classfinal-maven-plugin</artifactId><version>1.2.1</version><configuration><password>#</password><!-- #表示启动时不需要密码,事实上对于代码混淆来说,这个密码没什么用,它只是一个启动密码 --><packages>com.nick.gnss</packages><!-- 加密的包名,多个包用逗号分开--><excludes>org.spring</excludes></configuration><executions><execution><phase>package</phase><goals><goal>classFinal</goal></goals></execution></executions></plugin><plugin> <groupId>net.roseboy</groupId> <artifactId>classfinal-maven-plugin</artifactId> <version>1.2.1</version> <configuration> <password>#</password><!-- #表示启动时不需要密码,事实上对于代码混淆来说,这个密码没什么用,它只是一个启动密码 --> <packages>com.nick.gnss</packages><!-- 加密的包名,多个包用逗号分开--> <excludes>org.spring</excludes> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>classFinal</goal> </goals> </execution> </executions> </plugin><plugin> <groupId>net.roseboy</groupId> <artifactId>classfinal-maven-plugin</artifactId> <version>1.2.1</version> <configuration> <password>#</password><!-- #表示启动时不需要密码,事实上对于代码混淆来说,这个密码没什么用,它只是一个启动密码 --> <packages>com.nick.gnss</packages><!-- 加密的包名,多个包用逗号分开--> <excludes>org.spring</excludes> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>classFinal</goal> </goals> </execution> </executions> </plugin>
2.启动方式
1)无密码启动
java -jar gnss-server-1.0.0-encrypted.jarjava -jar gnss-server-1.0.0-encrypted.jarjava -jar gnss-server-1.0.0-encrypted.jar
2)有密码启动
java -javaagent:gnss-server-1.0.0-encrypted.jar="-pwd 123456" -jar gnss-server-1.0.0-encrypted.jarjava -javaagent:gnss-server-1.0.0-encrypted.jar="-pwd 123456" -jar gnss-server-1.0.0-encrypted.jarjava -javaagent:gnss-server-1.0.0-encrypted.jar="-pwd 123456" -jar gnss-server-1.0.0-encrypted.jar
3.反编译后的效果
所有的方法,return 0 或者 null. 方法体内部是空的。
![图片[1]-SpringBoot如何防止反编译?proguard+xjar 完美搞定-明恒博客](https://www.zym88.cn/wp-content/uploads/2024/08/frc-6c9b036f807c4572cfcd9d93c8883e4d.jpg)
四、引入proguard混淆
1.module中增加proguard.cfg文件
#指定Java的版本-target 1.8#proguard会对代码进行优化压缩,他会删除从未使用的类或者类成员变量等-dontshrink#是否关闭字节码级别的优化,如果不开启则设置如下配置-dontoptimize#混淆时不生成大小写混合的类名,默认是可以大小写混合-dontusemixedcaseclassnames# 对于类成员的命名的混淆采取唯一策略-useuniqueclassmembernames#混淆时不生成大小写混合的类名,默认是可以大小写混合-dontusemixedcaseclassnames#混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代-adaptclassstrings#对异常、注解信息予以保留-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod# 此选项将保存接口中的所有原始名称(不混淆)-->-keepnames interface ** { *; }# 此选项将保存所有软件包中的所有原始接口文件(不进行混淆)#-keep interface * extends * { *; }#保留参数名,因为控制器,或者Mybatis等接口的参数如果混淆会导致无法接受参数,xml文件找不到参数-keepparameternames# 保留枚举成员及方法-keepclassmembers enum * { *; }# 不混淆所有的set/get方法-keepclassmembers public class * {void set*(***);*** get*();}# 不混淆所有包含Component等注解的类-keep @org.springframework.context.annotation.Bean class * {*;}-keep @org.springframework.context.beans.factory.annotation.Autowired class * {*;}-keep @org.springframework.context.beans.factory.annotation.Value class * {*;}-keep @org.springframework.stereotype.Service class * {*;}-keep @org.springframework.stereotype.Component class * {*;}-keep @org.springframework.web.bind.annotation.RestController class * {*;}-keep @org.springframework.context.annotation.Configuration class * {*;}#忽略warn消息-ignorewarnings#忽略note消息-dontnote#打印配置信息-printconfiguration#启动类不需要混淆-keep class com.nick.GnssApplication {public static void main(java.lang.String[]);}#指定Java的版本 -target 1.8 #proguard会对代码进行优化压缩,他会删除从未使用的类或者类成员变量等 -dontshrink #是否关闭字节码级别的优化,如果不开启则设置如下配置 -dontoptimize #混淆时不生成大小写混合的类名,默认是可以大小写混合 -dontusemixedcaseclassnames # 对于类成员的命名的混淆采取唯一策略 -useuniqueclassmembernames #混淆时不生成大小写混合的类名,默认是可以大小写混合 -dontusemixedcaseclassnames #混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代 -adaptclassstrings #对异常、注解信息予以保留 -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod # 此选项将保存接口中的所有原始名称(不混淆)--> -keepnames interface ** { *; } # 此选项将保存所有软件包中的所有原始接口文件(不进行混淆) #-keep interface * extends * { *; } #保留参数名,因为控制器,或者Mybatis等接口的参数如果混淆会导致无法接受参数,xml文件找不到参数 -keepparameternames # 保留枚举成员及方法 -keepclassmembers enum * { *; } # 不混淆所有的set/get方法 -keepclassmembers public class * {void set*(***);*** get*();} # 不混淆所有包含Component等注解的类 -keep @org.springframework.context.annotation.Bean class * {*;} -keep @org.springframework.context.beans.factory.annotation.Autowired class * {*;} -keep @org.springframework.context.beans.factory.annotation.Value class * {*;} -keep @org.springframework.stereotype.Service class * {*;} -keep @org.springframework.stereotype.Component class * {*;} -keep @org.springframework.web.bind.annotation.RestController class * {*;} -keep @org.springframework.context.annotation.Configuration class * {*;} #忽略warn消息 -ignorewarnings #忽略note消息 -dontnote #打印配置信息 -printconfiguration #启动类不需要混淆 -keep class com.nick.GnssApplication { public static void main(java.lang.String[]); }#指定Java的版本 -target 1.8 #proguard会对代码进行优化压缩,他会删除从未使用的类或者类成员变量等 -dontshrink #是否关闭字节码级别的优化,如果不开启则设置如下配置 -dontoptimize #混淆时不生成大小写混合的类名,默认是可以大小写混合 -dontusemixedcaseclassnames # 对于类成员的命名的混淆采取唯一策略 -useuniqueclassmembernames #混淆时不生成大小写混合的类名,默认是可以大小写混合 -dontusemixedcaseclassnames #混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代 -adaptclassstrings #对异常、注解信息予以保留 -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod # 此选项将保存接口中的所有原始名称(不混淆)--> -keepnames interface ** { *; } # 此选项将保存所有软件包中的所有原始接口文件(不进行混淆) #-keep interface * extends * { *; } #保留参数名,因为控制器,或者Mybatis等接口的参数如果混淆会导致无法接受参数,xml文件找不到参数 -keepparameternames # 保留枚举成员及方法 -keepclassmembers enum * { *; } # 不混淆所有的set/get方法 -keepclassmembers public class * {void set*(***);*** get*();} # 不混淆所有包含Component等注解的类 -keep @org.springframework.context.annotation.Bean class * {*;} -keep @org.springframework.context.beans.factory.annotation.Autowired class * {*;} -keep @org.springframework.context.beans.factory.annotation.Value class * {*;} -keep @org.springframework.stereotype.Service class * {*;} -keep @org.springframework.stereotype.Component class * {*;} -keep @org.springframework.web.bind.annotation.RestController class * {*;} -keep @org.springframework.context.annotation.Configuration class * {*;} #忽略warn消息 -ignorewarnings #忽略note消息 -dontnote #打印配置信息 -printconfiguration #启动类不需要混淆 -keep class com.nick.GnssApplication { public static void main(java.lang.String[]); }
2.module pom文件引入
此处需要注意,proguard plugin需要放在repackage plugin之前,否则混淆没有效果。原理就是在打包之前将代码混淆,然后再打包。
<!--代码混淆proguard--><plugin><groupId>com.github.wvengen</groupId><artifactId>proguard-maven-plugin</artifactId><version>2.6.0</version><executions><!-- 以下配置说明执行mvn的package命令时候,会执行proguard--><execution><phase>package</phase><goals><goal>proguard</goal></goals></execution></executions><configuration><!-- 就是输入Jar的名称,我们要知道,代码混淆其实是将一个原始的jar,生成一个混淆后的jar,那么就会有输入输出。 --><injar>${project.build.finalName}.jar</injar><!-- 输出jar名称,输入输出jar同名的时候就是覆盖,也是比较常用的配置。 --><outjar>${project.build.finalName}.jar</outjar><!-- 是否混淆 默认是true --><obfuscate>true</obfuscate><!-- 配置一个文件,通常叫做proguard.cfg,该文件主要是配置options选项,也就是说使用proguard.cfg那么options下的所有内容都可以移到proguard.cfg中 --><proguardInclude>${project.basedir}/proguard.cfg</proguardInclude><!-- 额外的jar包,通常是项目编译所需要的jar --><libs><lib>${java.home}/lib/rt.jar</lib><lib>${java.home}/lib/jce.jar</lib><lib>${java.home}/lib/jsse.jar</lib></libs><!-- 对输入jar进行过滤比如,如下配置就是对META-INFO文件不处理。 --><inLibsFilter>!META-INF/**,!META-INF/versions/9/**.class</inLibsFilter><!-- 这是输出路径配置,但是要注意这个路径必须要包括injar标签填写的jar --><outputDirectory>${project.basedir}/target</outputDirectory><!--这里特别重要,此处主要是配置混淆的一些细节选项,比如哪些类不需要混淆,哪些需要混淆--><options><!-- 可以在此处写option标签配置,不过我上面使用了proguardInclude,故而我更喜欢在proguard.cfg中配置 --></options></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.3.7.RELEASE</version><configuration><mainClass>com.nick.GnssApplication</mainClass></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin><!--代码混淆proguard--> <plugin> <groupId>com.github.wvengen</groupId> <artifactId>proguard-maven-plugin</artifactId> <version>2.6.0</version> <executions> <!-- 以下配置说明执行mvn的package命令时候,会执行proguard--> <execution> <phase>package</phase> <goals> <goal>proguard</goal> </goals> </execution> </executions> <configuration> <!-- 就是输入Jar的名称,我们要知道,代码混淆其实是将一个原始的jar,生成一个混淆后的jar,那么就会有输入输出。 --> <injar>${project.build.finalName}.jar</injar> <!-- 输出jar名称,输入输出jar同名的时候就是覆盖,也是比较常用的配置。 --> <outjar>${project.build.finalName}.jar</outjar> <!-- 是否混淆 默认是true --> <obfuscate>true</obfuscate> <!-- 配置一个文件,通常叫做proguard.cfg,该文件主要是配置options选项,也就是说使用proguard.cfg那么options下的所有内容都可以移到proguard.cfg中 --> <proguardInclude>${project.basedir}/proguard.cfg</proguardInclude> <!-- 额外的jar包,通常是项目编译所需要的jar --> <libs> <lib>${java.home}/lib/rt.jar</lib> <lib>${java.home}/lib/jce.jar</lib> <lib>${java.home}/lib/jsse.jar</lib> </libs> <!-- 对输入jar进行过滤比如,如下配置就是对META-INFO文件不处理。 --> <inLibsFilter>!META-INF/**,!META-INF/versions/9/**.class</inLibsFilter> <!-- 这是输出路径配置,但是要注意这个路径必须要包括injar标签填写的jar --> <outputDirectory>${project.basedir}/target</outputDirectory> <!--这里特别重要,此处主要是配置混淆的一些细节选项,比如哪些类不需要混淆,哪些需要混淆--> <options> <!-- 可以在此处写option标签配置,不过我上面使用了proguardInclude,故而我更喜欢在proguard.cfg中配置 --> </options> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.3.7.RELEASE</version> <configuration> <mainClass>com.nick.GnssApplication</mainClass> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin><!--代码混淆proguard--> <plugin> <groupId>com.github.wvengen</groupId> <artifactId>proguard-maven-plugin</artifactId> <version>2.6.0</version> <executions> <!-- 以下配置说明执行mvn的package命令时候,会执行proguard--> <execution> <phase>package</phase> <goals> <goal>proguard</goal> </goals> </execution> </executions> <configuration> <!-- 就是输入Jar的名称,我们要知道,代码混淆其实是将一个原始的jar,生成一个混淆后的jar,那么就会有输入输出。 --> <injar>${project.build.finalName}.jar</injar> <!-- 输出jar名称,输入输出jar同名的时候就是覆盖,也是比较常用的配置。 --> <outjar>${project.build.finalName}.jar</outjar> <!-- 是否混淆 默认是true --> <obfuscate>true</obfuscate> <!-- 配置一个文件,通常叫做proguard.cfg,该文件主要是配置options选项,也就是说使用proguard.cfg那么options下的所有内容都可以移到proguard.cfg中 --> <proguardInclude>${project.basedir}/proguard.cfg</proguardInclude> <!-- 额外的jar包,通常是项目编译所需要的jar --> <libs> <lib>${java.home}/lib/rt.jar</lib> <lib>${java.home}/lib/jce.jar</lib> <lib>${java.home}/lib/jsse.jar</lib> </libs> <!-- 对输入jar进行过滤比如,如下配置就是对META-INFO文件不处理。 --> <inLibsFilter>!META-INF/**,!META-INF/versions/9/**.class</inLibsFilter> <!-- 这是输出路径配置,但是要注意这个路径必须要包括injar标签填写的jar --> <outputDirectory>${project.basedir}/target</outputDirectory> <!--这里特别重要,此处主要是配置混淆的一些细节选项,比如哪些类不需要混淆,哪些需要混淆--> <options> <!-- 可以在此处写option标签配置,不过我上面使用了proguardInclude,故而我更喜欢在proguard.cfg中配置 --> </options> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.3.7.RELEASE</version> <configuration> <mainClass>com.nick.GnssApplication</mainClass> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin>
3.反编译看效果
查看xxx.jar是否有混淆的效果,而不是xxx_proguard_base.jar
(此jar是没有混淆的原jar)
![图片[2]-SpringBoot如何防止反编译?proguard+xjar 完美搞定-明恒博客](https://www.zym88.cn/wp-content/uploads/2024/08/frc-b25478724591395d72b599b7fbc5e89e.jpg)
效果杠杠滴!!!需要试运行,并且注意配置proguard,否则会导致程序运行异常,这可能就是proguard的唯一缺点了吧,欢迎拍砖。。。
![图片[3]-SpringBoot如何防止反编译?proguard+xjar 完美搞定-明恒博客](https://www.zym88.cn/wp-content/uploads/2024/08/frc-944d94c2ee8185d4066ebe35461ab386.jpg)
4.运行查看效果
启动成功,没毛病
![图片[4]-SpringBoot如何防止反编译?proguard+xjar 完美搞定-明恒博客](https://www.zym88.cn/wp-content/uploads/2024/08/frc-4e0c6da1dd00add9fe50dc10833b7ee4.jpg)
五、引入xjar
1.parent pom文件引入
重点在最下面的xjar plugin
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.nick</groupId><artifactId>nick-server</artifactId><version>1.0.0</version><name>nick-server</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.3.7.RELEASE</spring-boot.version></properties><modules><module>gnss-server</module></modules><packaging>pom</packaging><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><!--代码加密--><plugin><groupId>com.github.core-lib</groupId><artifactId>xjar-maven-plugin</artifactId><version>v2.0.7</version><executions><execution><goals><goal>build</goal></goals><phase>package</phase><configuration><password>44889951235894612351265ABD123</password><mode>1</mode><sourceDir>${project.build.directory}</sourceDir><targetJar>${project.build.finalName}_x.jar</targetJar><includes><include>com/nick/**</include></includes></configuration></execution></executions></plugin></plugins></build></project><?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.nick</groupId> <artifactId>nick-server</artifactId> <version>1.0.0</version> <name>nick-server</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> </properties> <modules> <module>gnss-server</module> </modules> <packaging>pom</packaging> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <!--代码加密--> <plugin> <groupId>com.github.core-lib</groupId> <artifactId>xjar-maven-plugin</artifactId> <version>v2.0.7</version> <executions> <execution> <goals> <goal>build</goal> </goals> <phase>package</phase> <configuration> <password>44889951235894612351265ABD123</password> <mode>1</mode> <sourceDir>${project.build.directory}</sourceDir> <targetJar>${project.build.finalName}_x.jar</targetJar> <includes> <include>com/nick/**</include> </includes> </configuration> </execution> </executions> </plugin> </plugins> </build> </project><?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.nick</groupId> <artifactId>nick-server</artifactId> <version>1.0.0</version> <name>nick-server</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> </properties> <modules> <module>gnss-server</module> </modules> <packaging>pom</packaging> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <!--代码加密--> <plugin> <groupId>com.github.core-lib</groupId> <artifactId>xjar-maven-plugin</artifactId> <version>v2.0.7</version> <executions> <execution> <goals> <goal>build</goal> </goals> <phase>package</phase> <configuration> <password>44889951235894612351265ABD123</password> <mode>1</mode> <sourceDir>${project.build.directory}</sourceDir> <targetJar>${project.build.finalName}_x.jar</targetJar> <includes> <include>com/nick/**</include> </includes> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
需要放在module pom文件plugin 最后一个,保证xjar是最后一个执行plugin
<!--代码加密xjar--><plugin><groupId>com.github.core-lib</groupId><artifactId>xjar-maven-plugin</artifactId></plugin><!--代码加密xjar--> <plugin> <groupId>com.github.core-lib</groupId> <artifactId>xjar-maven-plugin</artifactId> </plugin><!--代码加密xjar--> <plugin> <groupId>com.github.core-lib</groupId> <artifactId>xjar-maven-plugin</artifactId> </plugin>
3.编译打包
![图片[5]-SpringBoot如何防止反编译?proguard+xjar 完美搞定-明恒博客](https://www.zym88.cn/wp-content/uploads/2024/08/frc-587be999c14fd2a0cc37a3790592bac4.jpg)
4.反编译看效果
效果杠杠滴
![图片[6]-SpringBoot如何防止反编译?proguard+xjar 完美搞定-明恒博客](https://www.zym88.cn/wp-content/uploads/2024/08/frc-be20bcf8d712b3b18331c0dab451c820.jpg)
5.运行查看效果
![图片[7]-SpringBoot如何防止反编译?proguard+xjar 完美搞定-明恒博客](https://www.zym88.cn/wp-content/uploads/2024/08/frc-ab71467fd25e4262f55aa1ffd7824b48.jpg)
六、proguard + xjar
将第四步和第五步融合即可,但是要注意pom文件中的plugin的先后问题,不然要么混淆失败,要么加密失败。
1.完整版的parent pom文件
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.nick</groupId><artifactId>nick-server</artifactId><version>1.0.0</version><name>nick-server</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.3.7.RELEASE</spring-boot.version></properties><modules><module>gnss-server</module></modules><packaging>pom</packaging><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><!--代码加密--><plugin><groupId>com.github.core-lib</groupId><artifactId>xjar-maven-plugin</artifactId><version>v2.0.7</version><executions><execution><goals><goal>build</goal></goals><phase>package</phase><configuration><password>44889951235894612351265ABD123</password><mode>1</mode><sourceDir>${project.build.directory}</sourceDir><targetJar>${project.build.finalName}_x.jar</targetJar><includes><include>com/nick/**</include></includes></configuration></execution></executions></plugin></plugins></build></project><?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.nick</groupId> <artifactId>nick-server</artifactId> <version>1.0.0</version> <name>nick-server</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> </properties> <modules> <module>gnss-server</module> </modules> <packaging>pom</packaging> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <!--代码加密--> <plugin> <groupId>com.github.core-lib</groupId> <artifactId>xjar-maven-plugin</artifactId> <version>v2.0.7</version> <executions> <execution> <goals> <goal>build</goal> </goals> <phase>package</phase> <configuration> <password>44889951235894612351265ABD123</password> <mode>1</mode> <sourceDir>${project.build.directory}</sourceDir> <targetJar>${project.build.finalName}_x.jar</targetJar> <includes> <include>com/nick/**</include> </includes> </configuration> </execution> </executions> </plugin> </plugins> </build> </project><?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.nick</groupId> <artifactId>nick-server</artifactId> <version>1.0.0</version> <name>nick-server</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> </properties> <modules> <module>gnss-server</module> </modules> <packaging>pom</packaging> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <!--代码加密--> <plugin> <groupId>com.github.core-lib</groupId> <artifactId>xjar-maven-plugin</artifactId> <version>v2.0.7</version> <executions> <execution> <goals> <goal>build</goal> </goals> <phase>package</phase> <configuration> <password>44889951235894612351265ABD123</password> <mode>1</mode> <sourceDir>${project.build.directory}</sourceDir> <targetJar>${project.build.finalName}_x.jar</targetJar> <includes> <include>com/nick/**</include> </includes> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
2.完整版的poguard.cfg
#指定Java的版本-target 1.8#proguard会对代码进行优化压缩,他会删除从未使用的类或者类成员变量等-dontshrink#是否关闭字节码级别的优化,如果不开启则设置如下配置-dontoptimize#混淆时不生成大小写混合的类名,默认是可以大小写混合-dontusemixedcaseclassnames# 对于类成员的命名的混淆采取唯一策略-useuniqueclassmembernames#混淆时不生成大小写混合的类名,默认是可以大小写混合-dontusemixedcaseclassnames#混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代-adaptclassstrings#对异常、注解信息予以保留-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod# 此选项将保存接口中的所有原始名称(不混淆)-->-keepnames interface ** { *; }# 此选项将保存所有软件包中的所有原始接口文件(不进行混淆)#-keep interface * extends * { *; }#保留参数名,因为控制器,或者Mybatis等接口的参数如果混淆会导致无法接受参数,xml文件找不到参数-keepparameternames# 保留枚举成员及方法-keepclassmembers enum * { *; }# 不混淆所有的set/get方法-keepclassmembers public class * {void set*(***);*** get*();}# 不混淆所有包含Component等注解的类-keep @org.springframework.context.annotation.Bean class * {*;}-keep @org.springframework.context.beans.factory.annotation.Autowired class * {*;}-keep @org.springframework.context.beans.factory.annotation.Value class * {*;}-keep @org.springframework.stereotype.Service class * {*;}-keep @org.springframework.stereotype.Component class * {*;}-keep @org.springframework.web.bind.annotation.RestController class * {*;}-keep @org.springframework.context.annotation.Configuration class * {*;}#忽略warn消息-ignorewarnings#忽略note消息-dontnote#打印配置信息-printconfiguration#启动类不需要混淆-keep class com.nick.GnssApplication {public static void main(java.lang.String[]);}#指定Java的版本 -target 1.8 #proguard会对代码进行优化压缩,他会删除从未使用的类或者类成员变量等 -dontshrink #是否关闭字节码级别的优化,如果不开启则设置如下配置 -dontoptimize #混淆时不生成大小写混合的类名,默认是可以大小写混合 -dontusemixedcaseclassnames # 对于类成员的命名的混淆采取唯一策略 -useuniqueclassmembernames #混淆时不生成大小写混合的类名,默认是可以大小写混合 -dontusemixedcaseclassnames #混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代 -adaptclassstrings #对异常、注解信息予以保留 -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod # 此选项将保存接口中的所有原始名称(不混淆)--> -keepnames interface ** { *; } # 此选项将保存所有软件包中的所有原始接口文件(不进行混淆) #-keep interface * extends * { *; } #保留参数名,因为控制器,或者Mybatis等接口的参数如果混淆会导致无法接受参数,xml文件找不到参数 -keepparameternames # 保留枚举成员及方法 -keepclassmembers enum * { *; } # 不混淆所有的set/get方法 -keepclassmembers public class * {void set*(***);*** get*();} # 不混淆所有包含Component等注解的类 -keep @org.springframework.context.annotation.Bean class * {*;} -keep @org.springframework.context.beans.factory.annotation.Autowired class * {*;} -keep @org.springframework.context.beans.factory.annotation.Value class * {*;} -keep @org.springframework.stereotype.Service class * {*;} -keep @org.springframework.stereotype.Component class * {*;} -keep @org.springframework.web.bind.annotation.RestController class * {*;} -keep @org.springframework.context.annotation.Configuration class * {*;} #忽略warn消息 -ignorewarnings #忽略note消息 -dontnote #打印配置信息 -printconfiguration #启动类不需要混淆 -keep class com.nick.GnssApplication { public static void main(java.lang.String[]); }#指定Java的版本 -target 1.8 #proguard会对代码进行优化压缩,他会删除从未使用的类或者类成员变量等 -dontshrink #是否关闭字节码级别的优化,如果不开启则设置如下配置 -dontoptimize #混淆时不生成大小写混合的类名,默认是可以大小写混合 -dontusemixedcaseclassnames # 对于类成员的命名的混淆采取唯一策略 -useuniqueclassmembernames #混淆时不生成大小写混合的类名,默认是可以大小写混合 -dontusemixedcaseclassnames #混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代 -adaptclassstrings #对异常、注解信息予以保留 -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod # 此选项将保存接口中的所有原始名称(不混淆)--> -keepnames interface ** { *; } # 此选项将保存所有软件包中的所有原始接口文件(不进行混淆) #-keep interface * extends * { *; } #保留参数名,因为控制器,或者Mybatis等接口的参数如果混淆会导致无法接受参数,xml文件找不到参数 -keepparameternames # 保留枚举成员及方法 -keepclassmembers enum * { *; } # 不混淆所有的set/get方法 -keepclassmembers public class * {void set*(***);*** get*();} # 不混淆所有包含Component等注解的类 -keep @org.springframework.context.annotation.Bean class * {*;} -keep @org.springframework.context.beans.factory.annotation.Autowired class * {*;} -keep @org.springframework.context.beans.factory.annotation.Value class * {*;} -keep @org.springframework.stereotype.Service class * {*;} -keep @org.springframework.stereotype.Component class * {*;} -keep @org.springframework.web.bind.annotation.RestController class * {*;} -keep @org.springframework.context.annotation.Configuration class * {*;} #忽略warn消息 -ignorewarnings #忽略note消息 -dontnote #打印配置信息 -printconfiguration #启动类不需要混淆 -keep class com.nick.GnssApplication { public static void main(java.lang.String[]); }
3.完整版的module pom文件
该pom文件中注意两点:
- 引入parent节点
- 需要放在最后一个plugin执行
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>nick-server</artifactId><groupId>com.nick</groupId><version>1.0.0</version></parent><modelVersion>4.0.0</modelVersion><groupId>com.nick</groupId><artifactId>gnss-server</artifactId><version>1.0.0</version><name>gnss-server</name><description>gnss-server</description><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.3.7.RELEASE</spring-boot.version><!--maven.build.timestamp保存了maven编译时间戳--><!--在Maven 3.2.2+中, maven.build.timestamp已被重新定义,显示UTC中的时间,比中国时间慢8个小时--><timestamp>${maven.build.timestamp}</timestamp><!--指定时间格式--><maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><!--1.2.80以下存在安全漏洞--><!--<version>1.2.78</version>--><version>1.2.83</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30.1.1-jre</version></dependency><!--nacos-web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><configuration><delimiters><delimiter>@</delimiter></delimiters><useDefaultDelimiters>false</useDefaultDelimiters></configuration></plugin><!--代码混淆proguard--><plugin><groupId>com.github.wvengen</groupId><artifactId>proguard-maven-plugin</artifactId><version>2.6.0</version><executions><!-- 以下配置说明执行mvn的package命令时候,会执行proguard--><execution><phase>package</phase><goals><goal>proguard</goal></goals></execution></executions><configuration><!-- 就是输入Jar的名称,我们要知道,代码混淆其实是将一个原始的jar,生成一个混淆后的jar,那么就会有输入输出。 --><injar>${project.build.finalName}.jar</injar><!-- 输出jar名称,输入输出jar同名的时候就是覆盖,也是比较常用的配置。 --><outjar>${project.build.finalName}.jar</outjar><!-- 是否混淆 默认是true --><obfuscate>true</obfuscate><!-- 配置一个文件,通常叫做proguard.cfg,该文件主要是配置options选项,也就是说使用proguard.cfg那么options下的所有内容都可以移到proguard.cfg中 --><proguardInclude>${project.basedir}/proguard.cfg</proguardInclude><!-- 额外的jar包,通常是项目编译所需要的jar --><libs><lib>${java.home}/lib/rt.jar</lib><lib>${java.home}/lib/jce.jar</lib><lib>${java.home}/lib/jsse.jar</lib></libs><!-- 对输入jar进行过滤比如,如下配置就是对META-INFO文件不处理。 --><inLibsFilter>!META-INF/**,!META-INF/versions/9/**.class</inLibsFilter><!-- 这是输出路径配置,但是要注意这个路径必须要包括injar标签填写的jar --><outputDirectory>${project.basedir}/target</outputDirectory><!--这里特别重要,此处主要是配置混淆的一些细节选项,比如哪些类不需要混淆,哪些需要混淆--><options><!-- 可以在此处写option标签配置,不过我上面使用了proguardInclude,故而我更喜欢在proguard.cfg中配置 --></options></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.3.7.RELEASE</version><configuration><mainClass>com.nick.GnssApplication</mainClass></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin><!--代码加密xjar--><plugin><groupId>com.github.core-lib</groupId><artifactId>xjar-maven-plugin</artifactId></plugin><!--classfinal加密程序--><!--<plugin>--><!--<groupId>net.roseboy</groupId>--><!--<artifactId>classfinal-maven-plugin</artifactId>--><!--<version>1.2.1</version>--><!--<configuration>--><!--<password>#</password><!– #表示启动时不需要密码,事实上对于代码混淆来说,这个密码没什么用,它只是一个启动密码 –>--><!--<packages>com.nick.gnss</packages><!– 加密的包名,多个包用逗号分开–>--><!--<excludes>org.spring</excludes>--><!--</configuration>--><!--<executions>--><!--<execution>--><!--<phase>package</phase>--><!--<goals>--><!--<goal>classFinal</goal>--><!--</goals>--><!--</execution>--><!--</executions>--><!--</plugin>--></plugins><resources><resource><directory>src/main/resources</directory><filtering>true</filtering></resource></resources></build></project><?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>nick-server</artifactId> <groupId>com.nick</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.nick</groupId> <artifactId>gnss-server</artifactId> <version>1.0.0</version> <name>gnss-server</name> <description>gnss-server</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> <!--maven.build.timestamp保存了maven编译时间戳--> <!--在Maven 3.2.2+中, maven.build.timestamp已被重新定义,显示UTC中的时间,比中国时间慢8个小时--> <timestamp>${maven.build.timestamp}</timestamp> <!--指定时间格式--> <maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.16</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <!--1.2.80以下存在安全漏洞--> <!--<version>1.2.78</version>--> <version>1.2.83</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.1.1-jre</version> </dependency> <!--nacos-web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <configuration> <delimiters> <delimiter>@</delimiter> </delimiters> <useDefaultDelimiters>false</useDefaultDelimiters> </configuration> </plugin> <!--代码混淆proguard--> <plugin> <groupId>com.github.wvengen</groupId> <artifactId>proguard-maven-plugin</artifactId> <version>2.6.0</version> <executions> <!-- 以下配置说明执行mvn的package命令时候,会执行proguard--> <execution> <phase>package</phase> <goals> <goal>proguard</goal> </goals> </execution> </executions> <configuration> <!-- 就是输入Jar的名称,我们要知道,代码混淆其实是将一个原始的jar,生成一个混淆后的jar,那么就会有输入输出。 --> <injar>${project.build.finalName}.jar</injar> <!-- 输出jar名称,输入输出jar同名的时候就是覆盖,也是比较常用的配置。 --> <outjar>${project.build.finalName}.jar</outjar> <!-- 是否混淆 默认是true --> <obfuscate>true</obfuscate> <!-- 配置一个文件,通常叫做proguard.cfg,该文件主要是配置options选项,也就是说使用proguard.cfg那么options下的所有内容都可以移到proguard.cfg中 --> <proguardInclude>${project.basedir}/proguard.cfg</proguardInclude> <!-- 额外的jar包,通常是项目编译所需要的jar --> <libs> <lib>${java.home}/lib/rt.jar</lib> <lib>${java.home}/lib/jce.jar</lib> <lib>${java.home}/lib/jsse.jar</lib> </libs> <!-- 对输入jar进行过滤比如,如下配置就是对META-INFO文件不处理。 --> <inLibsFilter>!META-INF/**,!META-INF/versions/9/**.class</inLibsFilter> <!-- 这是输出路径配置,但是要注意这个路径必须要包括injar标签填写的jar --> <outputDirectory>${project.basedir}/target</outputDirectory> <!--这里特别重要,此处主要是配置混淆的一些细节选项,比如哪些类不需要混淆,哪些需要混淆--> <options> <!-- 可以在此处写option标签配置,不过我上面使用了proguardInclude,故而我更喜欢在proguard.cfg中配置 --> </options> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.3.7.RELEASE</version> <configuration> <mainClass>com.nick.GnssApplication</mainClass> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <!--代码加密xjar--> <plugin> <groupId>com.github.core-lib</groupId> <artifactId>xjar-maven-plugin</artifactId> </plugin> <!--classfinal加密程序--> <!--<plugin>--> <!--<groupId>net.roseboy</groupId>--> <!--<artifactId>classfinal-maven-plugin</artifactId>--> <!--<version>1.2.1</version>--> <!--<configuration>--> <!--<password>#</password><!– #表示启动时不需要密码,事实上对于代码混淆来说,这个密码没什么用,它只是一个启动密码 –>--> <!--<packages>com.nick.gnss</packages><!– 加密的包名,多个包用逗号分开–>--> <!--<excludes>org.spring</excludes>--> <!--</configuration>--> <!--<executions>--> <!--<execution>--> <!--<phase>package</phase>--> <!--<goals>--> <!--<goal>classFinal</goal>--> <!--</goals>--> <!--</execution>--> <!--</executions>--> <!--</plugin>--> </plugins> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build> </project><?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>nick-server</artifactId> <groupId>com.nick</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.nick</groupId> <artifactId>gnss-server</artifactId> <version>1.0.0</version> <name>gnss-server</name> <description>gnss-server</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> <!--maven.build.timestamp保存了maven编译时间戳--> <!--在Maven 3.2.2+中, maven.build.timestamp已被重新定义,显示UTC中的时间,比中国时间慢8个小时--> <timestamp>${maven.build.timestamp}</timestamp> <!--指定时间格式--> <maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.16</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <!--1.2.80以下存在安全漏洞--> <!--<version>1.2.78</version>--> <version>1.2.83</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.1.1-jre</version> </dependency> <!--nacos-web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <configuration> <delimiters> <delimiter>@</delimiter> </delimiters> <useDefaultDelimiters>false</useDefaultDelimiters> </configuration> </plugin> <!--代码混淆proguard--> <plugin> <groupId>com.github.wvengen</groupId> <artifactId>proguard-maven-plugin</artifactId> <version>2.6.0</version> <executions> <!-- 以下配置说明执行mvn的package命令时候,会执行proguard--> <execution> <phase>package</phase> <goals> <goal>proguard</goal> </goals> </execution> </executions> <configuration> <!-- 就是输入Jar的名称,我们要知道,代码混淆其实是将一个原始的jar,生成一个混淆后的jar,那么就会有输入输出。 --> <injar>${project.build.finalName}.jar</injar> <!-- 输出jar名称,输入输出jar同名的时候就是覆盖,也是比较常用的配置。 --> <outjar>${project.build.finalName}.jar</outjar> <!-- 是否混淆 默认是true --> <obfuscate>true</obfuscate> <!-- 配置一个文件,通常叫做proguard.cfg,该文件主要是配置options选项,也就是说使用proguard.cfg那么options下的所有内容都可以移到proguard.cfg中 --> <proguardInclude>${project.basedir}/proguard.cfg</proguardInclude> <!-- 额外的jar包,通常是项目编译所需要的jar --> <libs> <lib>${java.home}/lib/rt.jar</lib> <lib>${java.home}/lib/jce.jar</lib> <lib>${java.home}/lib/jsse.jar</lib> </libs> <!-- 对输入jar进行过滤比如,如下配置就是对META-INFO文件不处理。 --> <inLibsFilter>!META-INF/**,!META-INF/versions/9/**.class</inLibsFilter> <!-- 这是输出路径配置,但是要注意这个路径必须要包括injar标签填写的jar --> <outputDirectory>${project.basedir}/target</outputDirectory> <!--这里特别重要,此处主要是配置混淆的一些细节选项,比如哪些类不需要混淆,哪些需要混淆--> <options> <!-- 可以在此处写option标签配置,不过我上面使用了proguardInclude,故而我更喜欢在proguard.cfg中配置 --> </options> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.3.7.RELEASE</version> <configuration> <mainClass>com.nick.GnssApplication</mainClass> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <!--代码加密xjar--> <plugin> <groupId>com.github.core-lib</groupId> <artifactId>xjar-maven-plugin</artifactId> </plugin> <!--classfinal加密程序--> <!--<plugin>--> <!--<groupId>net.roseboy</groupId>--> <!--<artifactId>classfinal-maven-plugin</artifactId>--> <!--<version>1.2.1</version>--> <!--<configuration>--> <!--<password>#</password><!– #表示启动时不需要密码,事实上对于代码混淆来说,这个密码没什么用,它只是一个启动密码 –>--> <!--<packages>com.nick.gnss</packages><!– 加密的包名,多个包用逗号分开–>--> <!--<excludes>org.spring</excludes>--> <!--</configuration>--> <!--<executions>--> <!--<execution>--> <!--<phase>package</phase>--> <!--<goals>--> <!--<goal>classFinal</goal>--> <!--</goals>--> <!--</execution>--> <!--</executions>--> <!--</plugin>--> </plugins> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build> </project>
![图片[8]-SpringBoot如何防止反编译?proguard+xjar 完美搞定-明恒博客](https://www.zym88.cn/wp-content/uploads/2024/08/frc-389b5e43fbb593c848d74ce4e9489400.jpg)
5.反编译查看效果
![图片[9]-SpringBoot如何防止反编译?proguard+xjar 完美搞定-明恒博客](https://www.zym88.cn/wp-content/uploads/2024/08/frc-6bcda3113d4ec0c2a3d68da36f612ca0.jpg)
OK, 效果杠杠滴,混淆+加密。
至此,混淆+加密搞定。
花了蛮多时间测试验证,兄弟们觉得疗效好,望不吝点赞啊,也欢迎各种拍砖,哈哈~~~~
4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
5 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报。
6 本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
暂无评论内容