XJar簡介
- Spring Boot JAR 安全加密運行工具, 同時支持的原生JAR
- 基於對JAR包內資源的加密以及拓展ClassLoader來構建的一套程序加密啟動, 動態解密運行的方案, 避免源碼泄露以及反編譯.
功能特性
- 無代碼侵入, 只需要把編譯好的JAR包通過工具加密即可.
- 完全內存解密, 降低源碼以及字節碼泄露或反編譯的風險.
- 支持所有JDK內置加解密算法.
- 可選擇需要加解密的字節碼或其他資源文件.
- 支持Maven插件, 加密更加便捷.
- 動態生成Go啟動器, 保護密碼不泄露.
環境依賴
JDK 1.7+
使用步驟
1. 添加依賴
<project>
<!-- 設置 jitpack.io 倉庫 -->
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<!-- 添加 XJar 依賴 -->
<dependencies>
<dependency>
<groupId>com.github.core-lib</groupId>
<artifactId>xjar</artifactId>
<version>4.0.2</version>
<!-- <scope>test</scope> -->
</dependency>
</dependencies>
</project>
- 必須添加 https://jitpack.io Maven倉庫.
- 如果使用 JUnit 測試類來運行加密可以將 XJar 依賴的 scope 設置為 test.
2. 加密源碼
XCryptos.encryption() .from("/path/to/read/plaintext.jar") .use("io.xjar") .include("/io/xjar/**/*.class") .include("/mapper/**/*Mapper.xml") .exclude("/static/**/*") .exclude("/conf/*") .to("/path/to/save/encrypted.jar");
3. 參數說明
| 方法名稱 | 參數列表 | 是否必選 | 方法說明 |
|---|---|---|---|
| from | (String jar) | 二選一 | 指定待加密JAR包路徑 |
| from | (File jar) | 指定待加密JAR包文件 | |
| use | (String password) | 二選一 | 指定加密密碼 |
| use | (String algorithm, int keysize, int ivsize, String password) | 指定加密算法及加密密碼 | |
| include | (String ant) | 可多次調用 | 指定要加密的資源相對於classpath的ANT路徑表達式 |
| include | (Pattern regex) | 可多次調用 | 指定要加密的資源相對於classpath的正則路徑表達式 |
| exclude | (String ant) | 可多次調用 | 指定不加密的資源相對於classpath的ANT路徑表達式 |
| exclude | (Pattern regex) | 可多次調用 | 指定不加密的資源相對於classpath的正則路徑表達式 |
| to | (String xJar) | 二選一 | 指定加密后JAR包輸出路徑, 並執行加密. |
| to | (File xJar) | 指定加密后JAR包輸出文件, 並執行加密. |
- 指定加密算法的時候密鑰長度以及向量長度必須在算法可支持范圍內, 具體加密算法的密鑰及向量長度請自行百度或谷歌.
- include 和 exclude 同時使用時即加密在include的范圍內且排除了exclude的資源.
4. 編譯腳本
# go build xjar.go
- 通過步驟2加密成功后XJar會在輸出的JAR包同目錄下生成一個名為 xjar.go 的的Go啟動器源碼文件.
- 將 xjar.go 在不同的平台進行編譯即可得到不同平台的啟動器可執行文件, 其中Windows下文件名為 xjar.exe 而Linux下為 xjar
- 用於編譯的機器需要安裝 Go 環境, 用於運行的機器則可不必安裝 Go 環境, 具體安裝教程請自行搜索.
- 由於啟動器自帶JAR包防篡改校驗, 故啟動器無法通用, 即便密碼相同也不行.
5.啟動運行
/path/to/xjar /path/to/java [OPTIONS] -jar /path/to/encrypted.jar [ARGS] /path/to/xjar /path/to/javaw [OPTIONS] -jar /path/to/encrypted.jar [ARGS] nohup /path/to/xjar /path/to/java [OPTIONS] -jar /path/to/encrypted.jar [ARGS]
- 在 Java 啟動命令前加上編譯好的Go啟動器可執行文件名(xjar)即可啟動運行加密后的JAR包.
- 若使用 nohup 方式啟動則 nohup 要放在Go啟動器可執行文件名(xjar)之前.
- 若Go啟動器可執行文件名(xjar)不在當前命令行所在目錄則要通過絕對路徑或相對路徑指定.
- 僅支持通過 -jar 方式啟動, 不支持-cp或-classpath的方式.
- -jar 后面必須緊跟着啟動的加密jar文件路徑
- 例子: 如果當前命令行就在 xjar 所在目錄, java 環境變量也設置好了 ./xjar java -Xms256m -Xmx1024m -jar /path/to/encrypted.jar
6. 使用舉例(window環境)
- 安裝配置好JDK、GO環境

- 引入依賴(步驟1所述),完成加密


- 編輯腳本(go build xjar.go),生成可執行文件

- 使用xjar啟動jar

- 驗證:修改jar並重新啟動


插件集成
Maven項目可通過集成 xjar-maven-plugin 以免去每次加密都要執行一次上述的代碼, 隨着Maven構建自動生成加密后的JAR和Go啟動器源碼文件.
<project>
<!-- 設置 jitpack.io 插件倉庫 -->
<pluginRepositories>
<pluginRepository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</pluginRepository>
</pluginRepositories>
<!-- 添加 XJar Maven 插件 -->
<build>
<plugins>
<plugin>
<groupId>com.github.core-lib</groupId>
<artifactId>xjar-maven-plugin</artifactId>
<version>4.0.2</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
<phase>package</phase>
<!-- 或使用
<phase>install</phase>
-->
<configuration>
<password>io.xjar</password>
<!-- optional
<algorithm/>
<keySize/>
<ivSize/>
<includes>
<include/>
</includes>
<excludes>
<exclude/>
</excludes>
<sourceDir/>
<sourceJar/>
<targetDir/>
<targetJar/>
-->
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
對於Spring Boot 項目或模塊, 該插件要后於 spring-boot-maven-plugin 插件執行, 有兩種方式:
- 將插件放置於 spring-boot-maven-plugin 的后面, 因為其插件的默認 phase 也是 package
- 將插件的 phase 設置為 install(默認值為:package), 打包命令采用 mvn clean install
也可以通過Maven命令執行
mvn xjar:build -Dxjar.password=io.xjar
mvn xjar:build -Dxjar.password=io.xjar -Dxjar.targetDir=/directory/to/save/target.xjar
但通常情況下是讓XJar插件綁定到指定的phase中自動執行, 這樣就能在項目構建的時候自動構建出加密的包
mvn clean package -Dxjar.password=io.xjar mvn clean install -Dxjar.password=io.xjar -Dxjar.targetDir=/directory/to/save/target.xjar
強烈建議
強烈建議不要在 pom.xml 的 xjar-maven-plugin 配置中寫上密碼,這樣會導致打包出來的 xjar 包中的 pom.xml 文件保留着密碼,極其容易暴露密碼!強烈推薦通過 mvn 命令來指定加密密鑰!
參數說明
| 參數名稱 | 命令參數名稱 | 參數說明 | 參數類型 | 缺省值 | 示例值 |
|---|---|---|---|---|---|
| password | -Dxjar.password | 密碼字符串 | String | 必須 | 任意字符串, io.xjar |
| algorithm | -Dxjar.algorithm | 加密算法名稱 | String | AES/CBC/PKCS5Padding | JDK內置加密算法, 如:AES/CBC/PKCS5Padding 和 DES/CBC/PKCS5Padding |
| keySize | -Dxjar.keySize | 密鑰長度 | int | 128 | 根據加密算法而定, 56, 128, 256 |
| ivSize | -Dxjar.ivSize | 密鑰向量長度 | int | 128 | 根據加密算法而定, 128 |
| sourceDir | -Dxjar.sourceDir | 源jar所在目錄 | File | ${project.build.directory} | 文件目錄 |
| sourceJar | -Dxjar.sourceJar | 源jar名稱 | String | ${project.build.finalName}.jar | 文件名稱 |
| targetDir | -Dxjar.targetDir | 目標jar存放目錄 | File | ${project.build.directory} | 文件目錄 |
| targetJar | -Dxjar.targetJar | 目標jar名稱 | String | ${project.build.finalName}.xjar | 文件名稱 |
| includes | -Dxjar.includes | 需要加密的資源路徑表達式 | String[] | 無 | io/xjar/** , mapper/*Mapper.xml , 支持Ant表達式 |
| excludes | -Dxjar.excludes | 無需加密的資源路徑表達式 | String[] | 無 | static/** , META-INF/resources/** , 支持Ant表達式 |
- 指定加密算法的時候密鑰長度以及向量長度必須在算法可支持范圍內, 具體加密算法的密鑰及向量長度請自行百度或谷歌.
- 當 includes 和 excludes 同時使用時即加密在includes的范圍內且排除了excludes的資源.
參考: https://github.com/core-lib/xjar
