1.版權(quán)聲明 本文是關(guān)于如何通過(guò)序列號(hào)來(lái)加載加密的class文件的闡述。
本文所提及的Resin hessian是Caucho公司的注冊(cè)產(chǎn)品名稱, 其版權(quán)規(guī)caucho所有。
本文可以轉(zhuǎn)載, 但是必須注明作者的Blog地址:
2. 本文的適用對(duì)象 作為技術(shù)人員,本文的技術(shù)細(xì)節(jié)涉及到Java語(yǔ)言的基礎(chǔ)知識(shí), 您在閱讀前應(yīng)該了解Java動(dòng)態(tài)裝載Class的機(jī)制,以及常規(guī)的Java加密的相關(guān)知識(shí), 同時(shí)本文假定您已經(jīng)具有開發(fā)web的基本能力, 了解jsp和servlet的運(yùn)作過(guò)程。
3.怎樣閱讀你可以在下面地址下載到本文所用到的Jar文件和加密工具
加密工具的下載:
關(guān)于序列號(hào)的生成部分, 鑒于保護(hù)公司產(chǎn)品的考慮就不再公開發(fā)布了, 有興趣的同仁可以用mail和我交流。
4. 概述4.1. 加密Java源碼的原因 Java源代碼經(jīng)過(guò)編譯以后在JVM中執(zhí)行。由于JVM界面是完全透明的,Java類文件能夠很容易通過(guò)反編譯器重新轉(zhuǎn)換成源代碼。因此,所有的算法、類文件等都可以以源代碼的形式被公開,使得軟件不能受到保護(hù),為了保護(hù)產(chǎn)權(quán),一般可以有以下幾種方法:
?。?)"模糊"類文件,把文件的名稱和方法換成000OOoo的方式,當(dāng)然只要你有足夠的耐心, 將這些編碼轉(zhuǎn)換成自己可以看懂的代碼, 并非難事。
?。?)流行的加密工具對(duì)源文件進(jìn)行加密,比如PGP(Pretty Good Privacy)或GPG(GNU Privacy Guard)。這時(shí),最終用戶在運(yùn)行應(yīng)用之前必須先進(jìn)行解密。但解密之后,最終用戶就有了一份不加密的類文件,這和事先不進(jìn)行加密沒(méi)有什么差別。
?。?)加密類文件,在運(yùn)行中JVM用定制的類裝載器(Class Loader)解密類文件。Java運(yùn)行時(shí)裝入字節(jié)碼的機(jī)制隱含地意味著可以對(duì)字節(jié)碼進(jìn)行修改。JVM每次裝入類文件時(shí)都需要一個(gè)稱為ClassLoader的對(duì)象,這個(gè)對(duì)象負(fù)責(zé)把新的類裝入正在運(yùn)行的JVM。JVM給ClassLoader一個(gè)包含了待裝入類(例如java.lang.Object)名字的字符串,然后由ClassLoader負(fù)責(zé)找到類文件,裝入原始數(shù)據(jù),并把它轉(zhuǎn)換成一個(gè)Class對(duì)象。
用戶下載的是加密過(guò)的類文件,在加密類文件裝入之時(shí)進(jìn)行解密,因此可以看成是一種即時(shí)解密器。由于解密后的字節(jié)碼文件永遠(yuǎn)不會(huì)保存到文件系統(tǒng),所以竊密者很難得到解密后的代碼。
由于把原始字節(jié)碼轉(zhuǎn)換成Class對(duì)象的過(guò)程完全由系統(tǒng)負(fù)責(zé),所以創(chuàng)建定制ClassLoader對(duì)象其實(shí)并不困難,只需先獲得原始數(shù)據(jù),接著就可以進(jìn)行包含解密在內(nèi)的任何轉(zhuǎn)換。
4.2. Java密碼體系和Java密碼擴(kuò)展 Java密碼體系(JCA)和Java密碼擴(kuò)展(JCE)的設(shè)計(jì)目的是為Java提供與實(shí)現(xiàn)無(wú)關(guān)的加密函數(shù)API。它們都用factory方法來(lái)創(chuàng)建類的例程,然后把實(shí)際的加密函數(shù)委托給提供者指定的底層引擎,引擎中為類提供了服務(wù)提供者接口在Java中實(shí)現(xiàn)數(shù)據(jù)的加密/解密,是使用其內(nèi)置的JCE(Java加密擴(kuò)展)來(lái)實(shí)現(xiàn)的。Java密碼體系結(jié)構(gòu)支持供應(yīng)商的互操作,同時(shí)支持硬件和軟件實(shí)現(xiàn)。
4.3. 本文采用的方式我們采用的是第三種方式, 將class文件加密作為產(chǎn)品的發(fā)行版本,但是為了讓這個(gè)加密的方式可以在不同的項(xiàng)目里面使用, 又將這個(gè)解密的處理做成webservice的方式來(lái)進(jìn)行.
5. 基本設(shè)計(jì)思想
這個(gè)過(guò)程可以劃分成5個(gè)部分: 1) 將加密的class文件傳遞到webService里面.
2) 由webService來(lái)查看Licence是里面, 是否有合法的信息, 譬如產(chǎn)品名稱, 版本, 授權(quán)用戶,已經(jīng)過(guò)期時(shí)間等, 有此決定是否繼續(xù)執(zhí)行第3個(gè)步驟
3) 如果一切驗(yàn)證通過(guò), 將由webService返回一個(gè)解密的文件
4) 由本地的webService來(lái)裝載這個(gè)class對(duì)象,
5) 構(gòu)造成一個(gè)class的instance
6.那個(gè)文件應(yīng)該被加密 在以前, 嘗試將自己的API進(jìn)行加密, 但是作為API本身在公司內(nèi)部發(fā)行, 這就要求我們每個(gè)programmer在編寫代碼的時(shí)候必須人手一個(gè)Licence才可以進(jìn)行正常的工作, 為API的升級(jí)和維護(hù)也帶來(lái)極大的不便, 為什么? 因?yàn)锳PI不能作為一個(gè)Jar發(fā)布, 只能以class的方式來(lái)發(fā)布.
那么. 我們應(yīng)該加密的是什么呢? 在我們?cè)O(shè)計(jì)web程序的時(shí)候, 一般的流程是, login 然后在session或cookie里面記錄他的身份信息, 譬如她是一個(gè)什么樣的用戶, 是學(xué)生或者教師還是管理員, 同時(shí), 我們要記錄他具有什么權(quán)限, 每個(gè)權(quán)限的操作范圍又是什么? 那么這個(gè)過(guò)程我們一般在用戶登陸, 和數(shù)據(jù)庫(kù)連接之后來(lái)進(jìn)行的, 這是一個(gè)復(fù)雜的邏輯操作過(guò)程,, 加密這個(gè)方法是一個(gè)好的想法, 這樣惡意的用戶, 即使把所有的其他class文件用jad來(lái)還原, 也無(wú)濟(jì)于事, 除非他可以猜出你在login的時(shí)候到底做了什么。
7. 怎樣加密自己的java文件7.2. 文件的加密 加密我們的文件, 我們采用的是JCE的算法來(lái)進(jìn)行的, 具體的加密實(shí)現(xiàn), 我再次不再敘述, 在google里面, 你可以獲取n多的文章在描述這個(gè)JCE的用法, 對(duì)于我們的文件, 已經(jīng)提供了一個(gè)windows的exe程序來(lái)之行,這個(gè)文件叫做encryption.exe
你可以用如下命令來(lái)加密自己的文件
這樣就可以把你的文件做成Jad等工具無(wú)法反編譯的文件了。
8. 從LicenceCenter獲取的產(chǎn)品信息無(wú)論再添加課程還是, 建立新的用戶的時(shí)候, 您都可能會(huì)有一個(gè)需求, 我怎么知道自己的產(chǎn)品授權(quán)給這個(gè)用戶什么樣的信息呢, 是否允許他再建立一個(gè)課程或者添加一個(gè)客戶?
我們提供的jar里面可以解決你的困惑:
代碼如下
如果這個(gè)產(chǎn)品在驗(yàn)證中心沒(méi)有注冊(cè)序列號(hào), 將返回null;
9.程序需要增加什么配置在licenceClient里面, 系統(tǒng)需要讀取licenceCenter的地址, 在您的web應(yīng)用發(fā)布的時(shí)候, 必須將webService的地址編寫成環(huán)境變量, 在web.xml里面增加一段代碼:
你可以將紅色的部分放在你的web server上訪問(wèn), 假設(shè)看到如下界面, 表示驗(yàn)證中心已經(jīng)安裝成功
10.關(guān)于驗(yàn)證中心的安裝驗(yàn)證中心的安裝文件為 licenceService1.0.1.zip
在你的操作系統(tǒng)里面解壓在一個(gè)目錄中。
在你的Java web server里面配置一個(gè)應(yīng)用, 譬如叫做:licenceCenter
以Resin為例子:在httpd.conf里面加上一下代碼:
其中在你的這個(gè)應(yīng)用中的web.xml文件必須包含
11. 常見(jiàn)問(wèn)題Q: 為什么不直接在webService里面加載好一個(gè)Class, 而是要在客戶端來(lái)用classLoader來(lái)裝載?
A: 很多的程序員問(wèn)過(guò)我這個(gè)問(wèn)題,其實(shí)很簡(jiǎn)單, 你如果知道classloader的機(jī)制, 就知道假設(shè)你擴(kuò)展login的實(shí)例用到你的另外一個(gè)對(duì)象, 譬如OnlineUser, 那么要在webService里面來(lái)裝載你的類, 我就必須擁有你這個(gè)類, 但是webservice里面是不知道你未來(lái)是要用到什么類的。
Q:為什么在redhat9上,訪問(wèn)驗(yàn)證中心會(huì)出現(xiàn)中文亂碼問(wèn)題?
A:是由于redhat9的默認(rèn)字符集不為GBK的緣故。一般采用將命令export LANG=zh_CN.GBK加在resin服務(wù)啟動(dòng)文件中。
13.關(guān)于作者OldJavaMan, 是一個(gè)Java的狂熱分子, 喜歡OpenSouce的東西, 無(wú)奈自己還要靠這個(gè)東西養(yǎng)家, 無(wú)法實(shí)現(xiàn)開源的做法, 期望有一天可以衣食無(wú)憂地編寫自己喜歡地程序, 并從中獲取自己的人生樂(lè)趣。
|
|
|