SpringBoot Jar 包加密防止反編譯實(shí)戰(zhàn)
今天給大家分享一個(gè) SpringBoot 程序 Jar 包加密的方式,通過代碼加密可以實(shí)現(xiàn)無(wú)法反編譯。
應(yīng)用場(chǎng)景就是當(dāng)需要把公司的產(chǎn)品部署到友方公司或者其他公司時(shí),可以防止客戶直接反編譯出來源碼,大大提升代碼的安全性。
版本
- springboot 2.6.8
- jdk8
一、proguard-maven-plugin
第一種方式就是使用代碼混淆的方式,可以參考proguard-maven-plugin插件使用,因?yàn)榕渲脧?fù)雜,用起來太麻煩,本文不做重點(diǎn)介紹。
https://github.com/wvengen/proguard-maven-plugin
二、classfinal-maven-plugin
第二種方式就是使用代碼加密的方式,classfinal-maven-plugin方式比較簡(jiǎn)單,只需要在pom.xml文件中引入一個(gè)plugin,然后簡(jiǎn)單的修改幾項(xiàng)配置即可使用。
這種方式不僅可以對(duì)代碼進(jìn)行加密,對(duì)配置文件application.yml、lib 下的依賴也可以加密。
還可以指定機(jī)器運(yùn)行程序。
https://gitee.com/roseboy/classfinal
三、實(shí)戰(zhàn)
下面我們實(shí)戰(zhàn)一下,首先創(chuàng)建一個(gè) SpringBoot 程序,在 pom.xml 中加入。
需要注意的是,該插件需要放到spring-boot-maven-plugin后面
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<!--
1. 加密后,方法體被清空,保留方法參數(shù)、注解等信息.主要兼容swagger文檔注解掃描
2. 方法體被清空后,反編譯只能看到方法名和注解,看不到方法體的具體內(nèi)容
3. 加密后的項(xiàng)目需要設(shè)置javaagent來啟動(dòng),啟動(dòng)過程中解密class,完全內(nèi)存解密,不留下任何解密后的文件
4. 啟動(dòng)加密后的jar,生成xxx-encrypted.jar,這個(gè)就是加密后的jar文件,加密后不可直接執(zhí)行
5. 無(wú)密碼啟動(dòng)方式,java -javaagent:xxx-encrypted.jar -jar xxx-encrypted.jar
6. 有密碼啟動(dòng)方式,java -javaagent:xxx-encrypted.jar='-pwd= 密碼' -jar xxx-encrypted.jar
-->
<groupId>net.roseboy</groupId>
<artifactId>classfinal-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<password>#</password><!-- #表示啟動(dòng)時(shí)不需要密碼,事實(shí)上對(duì)于代碼混淆來說,這個(gè)密碼沒什么用,它只是一個(gè)啟動(dòng)密碼 -->
<excludes>org.spring</excludes>
<packages>${groupId}</packages><!-- 加密的包名,多個(gè)包用逗號(hào)分開 -->
<cfgfiles>application.yml,application-dev.yml</cfgfiles><!-- 加密的配置文件,多個(gè)包用逗號(hào)分開 -->
<libjars>hutool-all.jar</libjars> <!-- jar包lib下面要加密的jar依賴文件,多個(gè)包用逗號(hào)分開 -->
<code>xxxxx</code> <!-- 指定機(jī)器啟動(dòng),機(jī)器碼 -->
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>classFinal</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
上述代碼中的機(jī)器碼可以使用如下工具生成,進(jìn)去之后點(diǎn)擊下載。
https://repo1.maven.org/maven2/net/roseboy/classfinal-fatjar/1.2.1/classfinal-fatjar-1.2.1.jar
然后執(zhí)行,注意最后參數(shù)為大寫的C。
java -jar classfinal-fatjar-1.2.1.jar -C
最后將輸出的機(jī)器碼放入到上方的 code 中即可。
執(zhí)行 Maven 命令打包即可,生成文件如下,其中EncryptDemo-0.0.1-SNAPSHOT-encrypted.jar為生成的加密jar 包。
如需提供給客戶,提供該包即可。
使用反編譯工具,查看 jar 包中配置文件,可以看到配置文件已經(jīng)為空。
反編譯工具我這里用的是 luyten。
https://github.com/deathmarine/Luyten/releases/tag/v0.5.4_Rebuilt_with_Latest_depenencies
查看代碼文件,可以看到方法體被清空,只保留了方法參數(shù)、注解等信息。
原理就是啟動(dòng)過程中進(jìn)行解密,全是內(nèi)存操作,非常安全。
無(wú)密碼啟動(dòng)
例如我的 jar 包名稱為EncryptDemo-0.0.1-SNAPSHOT-encrypted.jar,那么執(zhí)行命令如下:
java -javaagent:加密jar包的名稱 -jar 加密jar包的名稱
java -javaagent:EncryptDemo-0.0.1-SNAPSHOT-encrypted.jar -jar EncryptDemo-0.0.1-SNAPSHOT-encrypted.jar
有密碼啟動(dòng)
有密碼啟動(dòng)與無(wú)密碼啟動(dòng)類似,只是啟動(dòng)之后會(huì)提示輸入密碼,按照提示輸入密碼即可。
如果機(jī)器碼不匹配,會(huì)提示該項(xiàng)目不可在此機(jī)器上運(yùn)行!
正常啟動(dòng)截圖如下:
源代碼如下:https://github.com/zuiyu-main/EncryptDemo.git
分支:jar-encry
最后介紹一下 ClassFinal ,ClassFinal 能夠?qū)lass文件進(jìn)行加密,支持直接加密jar包或者war包,無(wú)需修改任務(wù)代碼,兼容spring framework,可避免源碼泄露或者字節(jié)碼被反編譯。
目前看官方介紹支持的功能如下:
- 支持編譯好的 jar/war 加密。
- 運(yùn)行加密項(xiàng)目,無(wú)需修改源代碼。
- 支持普通jar 包。springboot的jar包,tomcat的war包。
- 支持 spring framework、swagger等在啟動(dòng)過程中掃描注解或者生成字節(jié)碼的框架。
- 支持maven 插件,添加插件即可自動(dòng)加密。
- 支持加密lib文件下的依賴。
- 支持綁定機(jī)器運(yùn)行。
- 支持加密 springboot 配置文件。