jar包加密方案分享
前言
jar包相信大傢都很熟悉,是通過打包java工程而獲得的產物,但是jar包是有一個致命的缺點的,那就是很容易被反編譯,隻需要使用jd-gui就可以很容易的獲取到java源碼。
如果你想要防止別人反編譯做逆向工程,那麼對jar包進行一次加密就是一項很重要的工作瞭。
開源jar加密分為兩種一種代碼混淆,一種字節碼轉換。
字節碼混淆,主要思路就是的對類名,變量名和方法名,局部參數名進行替換,讓其命名變得無意義,很難讀懂,但不影響其邏輯,但對於有耐心的人,還是能看明白!具體實現是在編譯前做的混淆,還是編譯後做的混淆,這個沒用過不太清楚。
字節碼轉換,分為兩塊,一塊是加密,對編譯後class文件進行字節碼轉換(可以采用加密算法,字節碼異或運算或自己定義規則);一塊是解密,就是在類加載的時候對加密的字節碼進行解密。加密這塊因為在本地對class文件字節碼轉換,比較簡單,方式也隨意;解密這塊主要圍繞類加載器來做文章,又可分為java版實現和C/C++版實現,java版主要基於-agentJava:xxx.jar,通過Premain-Class,向Instrumentation註入ClassFileTransformer實現,自己在ClassFileTransformer中對需要解密的class文件進行解密;C/C++主要使用-agentpath:xxx.so,基於JVMTI通過C/C++實現,對類加載過程進行操作。
總體來說:代碼混淆和字節碼轉換可以結合,例如,先代碼混淆後,再對字節碼加密,運行時對字節碼解密。代碼混淆,上手最簡單,加密級別比較低,也容易破解。字節碼轉換,java版本對於java熟練人員上手很快,加密級別一般,個人理解該方式一個缺陷就是對於想加密的內容加密瞭,但解密方式暴露瞭,如果能夠隱藏好解密方式,加密安全系數還是蠻高;C/C++版加密級別最高,但需要對java和C/C++都很熟練,而且需要研究JVMTI相關知識,如果真的實現瞭基本無破解風險,不過對於SpringBoot等框架,其內部會直接分析class文件,有些坑需要解決。
另外一個問題就是,使用jar加密這塊,需要確定好是對運行的主程序jar包加密,還是第三方jar加密,其還是有部分差異的。
基礎環境準備
現在假設你的項目是一個maven項目(目前不使用maven的項目已經不多瞭),那麼加密起來特別的容易,
首先就是要在你的pom文件中增加插件倉庫地址,如下:
<pluginRepositories> <pluginRepository> <id>jitpack.io</id> <url>https://jitpack.io</url> </pluginRepository> </pluginRepositories>
然後在pom文件中增加如下插件:
<plugin> <groupId>com.github.core-lib</groupId> <artifactId>xjar-maven-plugin</artifactId> <version>4.0.1</version> <executions> <execution> <goals> <goal>build</goal> </goals> <phase>install</phase> <configuration> <includes> <include>/com/huc/**/*.class</include> <include>/mapper/**/*Mapper.xml</include> <include>/*.yml</include> </includes> <excludes> <exclude>/templates/**.*</exclude> <exclude>/static/**.*</exclude> </excludes> </configuration> </execution> </executions> </plugin>
這樣,我們的準備工作就做完瞭,需要註意的是,includes代表我們想要加密的內容,采用的是Ant表達式,excludes代表的是不需要加密的內容,同樣使用的Ant表達式。
一般情況下我們建議這兩處內容必填,如果不填寫,會加密整個jar包中的所有文件,這樣其實是沒有必要的,而且全部加密後啟動的時候也可能產生意料之外的錯誤。
另外要說明的是,加密後的jar包是需要通過golang環境運行的,所以我們需要提前把golang的運行環境安裝好,安裝過程請自行百度。
開始加密
現在我們就開始正式的加密工作瞭,加密過程非常簡單,隻需要使用maven的install命令即可自動打包,命令如下:
mvn clean install -Dxjar.password=password -Dmaven.test.skip=true
這裡的password可以自行指定密碼,是必填項。
執行後就會得到兩個文件:一個是xjar.go的go源文件,一個是你項目的xjar包,也就是加密後的jar包。
運行加密後的jar包
運行加密後的jar包是需要先編譯xjar.go源文件生成jar包啟動器的。編譯方式如下:
go build ./xjar.go
編譯後會生成xjar.exe啟動器(王子使用的是window系統,如果是linux系統就不是exe後綴瞭)。
之後使用如下命令即可運行加密後的jar包:
./xjar.exe java -jar ./**.xjar
可以看出,隻是在使用java -jar的前邊加上啟動器即可,還是很方便的。
後記
防止反編譯隻能防止jar包被逆向破解,如果想要限制用戶的使用時間,按時間付費需要怎麼做呢?
這就要說到license加密技術瞭,我們下篇文章就來說說如何在你的項目中增加license,限制用戶的使用。
其他的加密方案參考:
ClassFinal:Mr.K/ClassFinal
基於字節碼轉換java版,國人實現的,蠻不錯的,對SpringBoot支持也好,其邏輯就是基於-agentJava:xxx.jar這一套原理,加密時對class文件做瞭兩次處理,一次是對class文件的字節碼完全加密,一次是對class文件混淆,這個混淆是保留成員和方法,對方法內部實現進行隱藏;解密時,判斷如果該類是自己加密過的,找到完全加密的字節碼進行解密,如果不是自己加密的就跳過。其對class文件混淆,就是方便類似SpringBoot等三方框架直接分析class文件。好處就是,如果你是個工具包,加密後給其它人,其他人編程時引用或者編譯都不影響,但是運行時需要加密方支持,給出秘鑰之類的。比較靈活和好用,也存在該方式的統一缺陷,不過其支持主程序jar加密,也支持單獨的第三方工具jar加密。
JarEncrypt:https://github.com/zhikun0704/api-zxv-jvmit
基於字節碼轉換C/C++版,基於JVMIT個人實現的,稍微研究瞭下,其支持對部分class加密,對應一般java應用問題不大,但對於SpringBoot項目支持可能有些問題。因本人C++水平有限,沒有深層次研究,希望有C/C++和java都熟悉的大神有空搞一套完整的。
以上就是jar包加密方案分享的詳細內容,更多關於jar包加密的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- 使用Maven打包時包含資源文件和源碼到jar的方法
- springboot 2.0 mybatis mapper-locations掃描多個路徑的實現
- 解決maven沒有打包xml文件的問題
- SpringBoot分離打Jar包的兩種配置方式
- maven打包zip包含bin下啟動腳本的完整代碼