jar包加密方案分享
前言
jar包相信大家都很熟悉,是通過(guò)打包java工程而獲得的產(chǎn)物,但是jar包是有一個(gè)致命的缺點(diǎn)的,那就是很容易被反編譯,只需要使用jd-gui就可以很容易的獲取到j(luò)ava源碼。
如果你想要防止別人反編譯做逆向工程,那么對(duì)jar包進(jìn)行一次加密就是一項(xiàng)很重要的工作了。
開(kāi)源jar加密分為兩種一種代碼混淆,一種字節(jié)碼轉(zhuǎn)換。
字節(jié)碼混淆,主要思路就是的對(duì)類(lèi)名,變量名和方法名,局部參數(shù)名進(jìn)行替換,讓其命名變得無(wú)意義,很難讀懂,但不影響其邏輯,但對(duì)于有耐心的人,還是能看明白!具體實(shí)現(xiàn)是在編譯前做的混淆,還是編譯后做的混淆,這個(gè)沒(méi)用過(guò)不太清楚。
字節(jié)碼轉(zhuǎn)換,分為兩塊,一塊是加密,對(duì)編譯后class文件進(jìn)行字節(jié)碼轉(zhuǎn)換(可以采用加密算法,字節(jié)碼異或運(yùn)算或自己定義規(guī)則);一塊是解密,就是在類(lèi)加載的時(shí)候?qū)用艿淖止?jié)碼進(jìn)行解密。加密這塊因?yàn)樵诒镜貙?duì)class文件字節(jié)碼轉(zhuǎn)換,比較簡(jiǎn)單,方式也隨意;解密這塊主要圍繞類(lèi)加載器來(lái)做文章,又可分為java版實(shí)現(xiàn)和C/C++版實(shí)現(xiàn),java版主要基于-agentJava:xxx.jar,通過(guò)Premain-Class,向Instrumentation注入ClassFileTransformer實(shí)現(xiàn),自己在ClassFileTransformer中對(duì)需要解密的class文件進(jìn)行解密;C/C++主要使用-agentpath:xxx.so,基于JVMTI通過(guò)C/C++實(shí)現(xiàn),對(duì)類(lèi)加載過(guò)程進(jìn)行操作。
總體來(lái)說(shuō):代碼混淆和字節(jié)碼轉(zhuǎn)換可以結(jié)合,例如,先代碼混淆后,再對(duì)字節(jié)碼加密,運(yùn)行時(shí)對(duì)字節(jié)碼解密。代碼混淆,上手最簡(jiǎn)單,加密級(jí)別比較低,也容易破解。字節(jié)碼轉(zhuǎn)換,java版本對(duì)于java熟練人員上手很快,加密級(jí)別一般,個(gè)人理解該方式一個(gè)缺陷就是對(duì)于想加密的內(nèi)容加密了,但解密方式暴露了,如果能夠隱藏好解密方式,加密安全系數(shù)還是蠻高;C/C++版加密級(jí)別最高,但需要對(duì)java和C/C++都很熟練,而且需要研究JVMTI相關(guān)知識(shí),如果真的實(shí)現(xiàn)了基本無(wú)破解風(fēng)險(xiǎn),不過(guò)對(duì)于SpringBoot等框架,其內(nèi)部會(huì)直接分析class文件,有些坑需要解決。
另外一個(gè)問(wèn)題就是,使用jar加密這塊,需要確定好是對(duì)運(yùn)行的主程序jar包加密,還是第三方j(luò)ar加密,其還是有部分差異的。
基礎(chǔ)環(huán)境準(zhǔn)備
現(xiàn)在假設(shè)你的項(xiàng)目是一個(gè)maven項(xiàng)目(目前不使用maven的項(xiàng)目已經(jīng)不多了),那么加密起來(lái)特別的容易,
首先就是要在你的pom文件中增加插件倉(cāng)庫(kù)地址,如下:
<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>
這樣,我們的準(zhǔn)備工作就做完了,需要注意的是,includes代表我們想要加密的內(nèi)容,采用的是Ant表達(dá)式,excludes代表的是不需要加密的內(nèi)容,同樣使用的Ant表達(dá)式。
一般情況下我們建議這兩處內(nèi)容必填,如果不填寫(xiě),會(huì)加密整個(gè)jar包中的所有文件,這樣其實(shí)是沒(méi)有必要的,而且全部加密后啟動(dòng)的時(shí)候也可能產(chǎn)生意料之外的錯(cuò)誤。
另外要說(shuō)明的是,加密后的jar包是需要通過(guò)golang環(huán)境運(yùn)行的,所以我們需要提前把golang的運(yùn)行環(huán)境安裝好,安裝過(guò)程請(qǐng)自行百度。
開(kāi)始加密
現(xiàn)在我們就開(kāi)始正式的加密工作了,加密過(guò)程非常簡(jiǎn)單,只需要使用maven的install命令即可自動(dòng)打包,命令如下:
mvn clean install -Dxjar.password=password -Dmaven.test.skip=true
這里的password可以自行指定密碼,是必填項(xiàng)。
執(zhí)行后就會(huì)得到兩個(gè)文件:一個(gè)是xjar.go的go源文件,一個(gè)是你項(xiàng)目的xjar包,也就是加密后的jar包。
運(yùn)行加密后的jar包
運(yùn)行加密后的jar包是需要先編譯xjar.go源文件生成jar包啟動(dòng)器的。編譯方式如下:
go build ./xjar.go
編譯后會(huì)生成xjar.exe啟動(dòng)器(王子使用的是window系統(tǒng),如果是linux系統(tǒng)就不是exe后綴了)。
之后使用如下命令即可運(yùn)行加密后的jar包:
./xjar.exe java -jar ./**.xjar
可以看出,只是在使用java -jar的前邊加上啟動(dòng)器即可,還是很方便的。
后記
防止反編譯只能防止jar包被逆向破解,如果想要限制用戶的使用時(shí)間,按時(shí)間付費(fèi)需要怎么做呢?
這就要說(shuō)到license加密技術(shù)了,我們下篇文章就來(lái)說(shuō)說(shuō)如何在你的項(xiàng)目中增加license,限制用戶的使用。
其他的加密方案參考:
ClassFinal:Mr.K/ClassFinal
基于字節(jié)碼轉(zhuǎn)換java版,國(guó)人實(shí)現(xiàn)的,蠻不錯(cuò)的,對(duì)SpringBoot支持也好,其邏輯就是基于-agentJava:xxx.jar這一套原理,加密時(shí)對(duì)class文件做了兩次處理,一次是對(duì)class文件的字節(jié)碼完全加密,一次是對(duì)class文件混淆,這個(gè)混淆是保留成員和方法,對(duì)方法內(nèi)部實(shí)現(xiàn)進(jìn)行隱藏;解密時(shí),判斷如果該類(lèi)是自己加密過(guò)的,找到完全加密的字節(jié)碼進(jìn)行解密,如果不是自己加密的就跳過(guò)。其對(duì)class文件混淆,就是方便類(lèi)似SpringBoot等三方框架直接分析class文件。好處就是,如果你是個(gè)工具包,加密后給其它人,其他人編程時(shí)引用或者編譯都不影響,但是運(yùn)行時(shí)需要加密方支持,給出秘鑰之類(lèi)的。比較靈活和好用,也存在該方式的統(tǒng)一缺陷,不過(guò)其支持主程序jar加密,也支持單獨(dú)的第三方工具jar加密。
JarEncrypt:https://github.com/zhikun0704/api-zxv-jvmit
基于字節(jié)碼轉(zhuǎn)換C/C++版,基于JVMIT個(gè)人實(shí)現(xiàn)的,稍微研究了下,其支持對(duì)部分class加密,對(duì)應(yīng)一般java應(yīng)用問(wèn)題不大,但對(duì)于SpringBoot項(xiàng)目支持可能有些問(wèn)題。因本人C++水平有限,沒(méi)有深層次研究,希望有C/C++和java都熟悉的大神有空搞一套完整的。
以上就是jar包加密方案分享的詳細(xì)內(nèi)容,更多關(guān)于jar包加密的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用Springboot實(shí)現(xiàn)word在線編輯保存
PageOffice目前支持的Web編程語(yǔ)言及架構(gòu)有:Java(JSP、SSH、MVC等),ASP.NET(C#、VB.NET、MVC、Razor等),PHP,ASP,本篇文章就帶你使用Springboot整合PageOffice實(shí)現(xiàn)word在線編輯保存2021-08-08java用LocalDateTime類(lèi)獲取當(dāng)天時(shí)間、前一天時(shí)間及本周/本月的開(kāi)始和結(jié)束時(shí)間
這篇文章主要給大家介紹了關(guān)于java使用LocalDateTime類(lèi)獲取當(dāng)天時(shí)間、前一天時(shí)間及本周/本月的開(kāi)始和結(jié)束時(shí)間的相關(guān)資料,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08java中List對(duì)象列表實(shí)現(xiàn)去重或取出及排序的方法
這篇文章主要介紹了關(guān)于java中List對(duì)象列表實(shí)現(xiàn)去重或取出以及排序的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-08-08JavaGUI實(shí)現(xiàn)隨機(jī)單詞答題游戲
這篇文章主要為大家詳細(xì)介紹了JavaGUI實(shí)現(xiàn)隨機(jī)單詞答題游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12Spring Boot集成Redis實(shí)戰(zhàn)操作功能
這篇文章主要介紹了Spring Boot集成Redis實(shí)戰(zhàn)操作,包括如何集成redis以及redis的一些優(yōu)點(diǎn),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-11-11Java轉(zhuǎn)換流(InputStreamReader/OutputStreamWriter)的使用
本文主要介紹了Java轉(zhuǎn)換流(InputStreamReader/OutputStreamWriter)的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01