背景
一般公司開發的項目上線前都會做安全審核,為了保護一些私密代碼和一些敏感信息,均需要加密處理,比如各種密碼、license處理的等,就用到jar包混淆。
混淆工具
jar包混淆工具挺多的,實現原理不盡相同,這里使用的classfinal,
classfinal介紹
ClassFinal是一款java class文件安全加密工具,支持直接加密jar包或war包,無需修改任何項目代碼,兼容spring-framework;可避免源碼泄漏或字節碼被反編譯。
Gitee: https://gitee.com/roseboy/classfinal
項目模塊說明
- classfinal-core: ClassFinal的核心模塊,幾乎所有加密的代碼都在這里;
- classfinal-fatjar: ClassFinal打包成獨立運行的jar包;
- classfinal-maven-plugin: ClassFinal加密的maven插件;
功能特性
- 無需修改原項目代碼,只要把編譯好的jar/war包用本工具加密即可。
- 運行加密項目時,無需求修改tomcat,spring等源代碼。
- 支持普通jar包、springboot jar包以及普通java web項目編譯的war包。
- 支持spring framework、swagger等需要在啟動過程中掃描注解或生成字節碼的框架。
- 支持maven插件,添加插件后在打包過程中自動加密。
- 支持加密WEB-INF/lib或BOOT-INF/lib下的依賴jar包。
- 支持綁定機器,項目加密后只能在特定機器運行。
- 支持加密springboot的配置文件。
環境依賴
JDK 1.8 +
使用說明
下載
加密
執行以下命令
java -jar classfinal-fatjar.jar -file yourproject.jar -libjars a.jar,b.jar -packages com.yourpackage,com.yourpackage2 -exclude com.yourpackage.Main -pwd 123456 -Y 參數說明 -file 加密的jar/war完整路徑 -packages 加密的包名(可為空,多個用","分割) -libjars jar/war包lib下要加密jar文件名(可為空,多個用","分割) -cfgfiles 需要加密的配置文件,一般是classes目錄下的yml或properties文件(可為空,多個用","分割) -exclude 排除的類名(可為空,多個用","分割) -classpath 外部依賴的jar目錄,例如/tomcat/lib(可為空,多個用","分割) -pwd 加密密碼,如果是#號,則使用無密碼模式加密 -code 機器碼,在綁定的機器生成,加密后只可在此機器上運行 -Y 無需確認,不加此參數會提示確認以上信息
結果: 生成 yourpaoject-encrypted.jar,這個就是加密后的jar文件;加密后的文件不可直接執行,需要配置javaagent。
注: 以上示例是直接用參數執行,也可以直接執行 java -jar classfinal-fatjar.jar按照步驟提示輸入信息完成加密。
maven插件方式
在要加密的項目pom.xml中加入以下插件配置,目前最新版本是:1.2.1。
<plugin> <!-- https://gitee.com/roseboy/classfinal --> <groupId>net.roseboy</groupId> <artifactId>classfinal-maven-plugin</artifactId> <version>${classfinal.version}</version> <configuration> <password>000000</password><!--加密打包之后pom.xml會被刪除,不用擔心在jar包里找到此密碼--> <packages>com.yourpackage,com.yourpackage2</packages> <cfgfiles>application.yml</cfgfiles> <excludes>org.spring</excludes> <libjars>a.jar,b.jar</libjars> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>classFinal</goal> </goals> </execution> </executions> </plugin>
運行mvn package時會在target下自動加密生成yourpaoject-encrypted.jar。
maven插件的參數名稱與直接運行的參數相同,請參考上節的參數說明。
無密碼模式
加密時-pwd參數設為#,啟動時可不用輸入密碼; 如果是war包,啟動時指定參數 -nopwd,跳過輸密碼過程。
機器綁定
機器綁定只允許加密的項目在特定的機器上運行;
在需要綁定的機器上執行以下命令,生成機器碼
java -jar classfinal-fatjar.jar -C
加密時用-code指定機器碼。機器綁定可同時支持機器碼+密碼的方式加密。
啟動加密后的jar
加密后的項目需要設置javaagent來啟動,項目在啟動過程中解密class,完全內存解密,不留下任何解密后的文件。
解密功能已經自動加入到 yourpaoject-encrypted.jar中,所以啟動時-javaagent與-jar相同,不需要額外的jar包。
啟動jar項目執行以下命令:
java -javaagent:yourproject-encrypted.jar='-pwd 0000000' -jar yourproject-encrypted.jar //參數說明 // -pwd 加密項目的密碼 // -pwdname 環境變量中密碼的名字
或者不加pwd參數直接啟動,啟動后在控制台里輸入密碼,推薦使用這種方式:
java -javaagent:yourpaoject-encrypted.jar -jar yourproject-encrypted.jar
使用nohup命令啟動時,如果系統支持gui,會彈出輸入密碼的界面,如果是純命令行下,不支持gui,則需要在同級目錄下的classfinal.txt或yourpaoject-encrypted.classfinal.txt中寫入密碼,項目讀取到密碼后會清空此文件。
密碼讀取順序已經改為:參數獲取密碼||環境變量獲取密碼||密碼文件獲取密碼||控制台輸入密碼||GUI輸入密碼||退出
tomcat下運行加密后的war
將加密后的war放在tomcat/webapps下, tomcat/bin/catalina 增加以下配置:
//linux下 catalina.sh CATALINA_OPTS="$CATALINA_OPTS -javaagent:classfinal-fatjar.jar='-pwd 0000000'"; export CATALINA_OPTS; //win下catalina.bat set JAVA_OPTS="-javaagent:classfinal-fatjar.jar='-pwd 000000'" //參數說明 // -pwd 加密項目的密碼 // -nopwd 無密碼加密時啟動加上此參數,跳過輸密碼過程 // -pwdname 環境變量中密碼的名字
本工具使用AES算法加密class文件,密碼是保證不被破解的關鍵,請保存好密碼,請勿泄漏。
密碼一旦忘記,項目不可啟動且無法恢復,請牢記密碼。
本工具加密后,原始的class文件並不會完全被加密,只是方法體被清空,保留方法參數、注解等信息,這是為了兼容spring,swagger等掃描注解的框架; 方法體被清空后,反編譯者只能看到方法名和注解,看不到方法的具體內容;當class被classloader加載時,真正的方法體會被解密注入。
為了保證項目在運行時的安全,啟動jvm時請加參數: -XX:+DisableAttachMechanism 。