1.著作權聲明 本文是關於如何通過序號來載入加密的class檔案的闡述。 本文所提及的Resin hessian是Caucho公司的註冊產品名稱, 其著作權規caucho所有。本文可以轉載, 但是必須註明作者的Blog地址:http://blog.csdn.net/oldjavaman2. 本文的適用對象 作為技術人員,本文的技術細節涉及到Java語言的基礎知識, 您在閱讀前應該瞭解Java動態裝載Class的機制,以及常規的Java加密的相關知識, 同時本文假定您已經具有開發web的基本能力, 瞭解jsp和servlet的運作過程。3.怎樣閱讀你可以在下面地址下載到本文所用到的Jar檔案和加密工具http://www.collegesoft.com.cn/download/licenceClient_1.0.3.jar加密工具的下載:http://www.collegesoft.com.cn/download/encryption.exe關於序號的產生部分, 鑒於保護公司產品的考慮就不再公開發布了, 有興趣的同仁可以用mail和我交流。 4. 概述4.1. 加密Java源碼的原因 Java原始碼經過編譯以後在JVM中執行。由於JVM介面是完全透明的,Java類檔案能夠很容易通過反編譯器重新轉換成原始碼。因此,所有的演算法、類檔案等都可以以原始碼的形式被公開,使得軟體不能受到保護,為了保護產權,一般可以有以下幾種方法: (1)"模糊"類檔案,把檔案的名稱和方法換成000OOoo的方式,當然只要你有足夠的耐心, 將這些編碼轉換成自己可以看懂的代碼, 並非難事。 (2)流行的加密工具對源檔案進行加密,比如PGP(Pretty Good Privacy)或GPG(GNU Privacy Guard)。這時,終端使用者在運行應用之前必須先進行解密。但解密之後,終端使用者就有了一份不加密的類檔案,這和事先不進行加密沒有什麼差別。 (3)加密類檔案,在運行中JVM用定製的類裝載器(Class Loader)解密類檔案。Java運行時裝入位元組碼的機制隱含地意味著可以對位元組碼進行修改。JVM每次裝入類檔案時都需要一個稱為ClassLoader的對象,這個對象負責把新的類裝入正在啟動並執行JVM。JVM給ClassLoader一個包含了待裝入類(例如java.lang.Object)名字的字串,然後由ClassLoader負責找到類檔案,裝入未經處理資料,並把它轉換成一個Class對象。 使用者下載的是加密過的類檔案,在加密類檔案裝入之時進行解密,因此可以看成是一種即時解密器。由於解密後的位元組碼檔案永遠不會儲存到檔案系統,所以竊密者很難得到解密後的代碼。 由於把原始位元組碼轉換成Class對象的過程完全由系統負責,所以建立定製ClassLoader對象其實並不困難,只需先獲得未經處理資料,接著就可以進行包含解密在內的任何轉換。 4.2. Java密碼體系和Java密碼擴充 Java密碼體系(JCA)和Java密碼擴充(JCE)的設計目的是為Java提供與實現無關的加密函數API。它們都用factory方法來建立類的常式,然後把實際的加密函數委託給提供者指定的底層引擎,引擎中為類提供了服務提供者介面在Java中實現資料的加密/解密,是使用其內建的JCE(Java加密擴充)來實現的。Java密碼體繫結構支援供應商的互操作,同時支援硬體和軟體實現。4.3. 本文採用的方式我們採用的是第三種方式, 將class檔案加密作為產品的發行版本,但是為了讓這個加密的方式可以在不同的項目裡面使用, 又將這個解密的處理做成webservice的方式來進行.5. 基本設計思想
這個過程可以劃分成5個部分:
1) 將加密的class檔案傳遞到webService裡面.2) 由webService來查看Licence是裡面, 是否有合法的資訊, 譬如產品名稱, 版本, 授權使用者,已經到期時間等, 有此決定是否繼續執行第3個步驟3) 如果一切驗證通過, 將由webService返回一個解密的檔案4) 由本地的webService來裝載這個class對象, 5) 構造成一個class的instance 6.那個檔案應該被加密 在以前, 嘗試將自己的API進行加密, 但是作為API本身在公司內部發行, 這就要求我們每個programmer在編寫代碼的時候必須人手一個Licence才可以進行正常的工作, 為API的升級和維護也帶來極大的不便, 為什麼? 因為API不能作為一個Jar發布, 只能以class的方式來發布. 那麼. 我們應該加密的是什麼呢? 在我們設計web程式的時候, 一般的流程是, login 然後在session或cookie裡面記錄他的身份資訊, 譬如她是一個什麼樣的使用者, 是學生或者教師還是管理員, 同時, 我們要記錄他具有什麼許可權, 每個許可權的操作範圍又是什麼? 那麼這個過程我們一般在使用者登陸, 和資料庫連接之後來進行的, 這是一個複雜的邏輯操作過程,, 加密這個方法是一個好的想法, 這樣惡意的使用者, 即使把所有的其他class檔案用jad來還原, 也無濟於事, 除非他可以猜出你在login的時候到底做了什麼。 7. 怎樣加密自己的java檔案7.2. 檔案的加密 加密我們的檔案, 我們採用的是JCE的演算法來進行的, 具體的加密實現, 我再次不再敘述, 在google裡面, 你可以擷取n多的文章在描述這個JCE的用法, 對於我們的檔案, 已經提供了一個windows的exe程式來之行,這個檔案叫做encryption.exe你可以用如下命令來加密自己的檔案
| c:> encryption –encrypto myClass.class |
這樣就可以把你的檔案做成Jad等工具無法反編譯的檔案了。 8. 從LicenceCenter擷取的產品資訊無論再添加課程還是, 建立新的使用者的時候, 您都可能會有一個需求, 我怎麼知道自己的產品授權給這個使用者什麼樣的資訊呢, 是否允許他再建立一個課程或者添加一個客戶? 我們提供的jar裡面可以解決你的困惑:代碼如下
| LicenceFactory licenceFactory=new LicenceFactory(); licenceFactory.getLicence("urProductName"); |
如果這個產品在驗證中心沒有註冊序號, 將返回null; 9.程式需要增加什麼配置在licenceClient裡面, 系統需要讀取licenceCenter的地址, 在您的web應用發布的時候, 必須將webService的地址編寫成環境變數, 在web.xml裡面增加一段代碼:
| <env-entry> <env-entry-name>licence_service_url</env-entry-name> <env-entry-value>http://192.168.2.212:8080/licenceCenter/LicenceService</env-entry-value> <env-entry-type>java.lang.String</env-entry-type> </env-entry> |
你可以將紅色的部分放在你的web server上訪問, 假設看到如下介面, 表示驗證中心已經安裝成功 10.關於驗證中心的安裝驗證中心的安裝檔案為 licenceService1.0.1.zip在你的作業系統裡面解壓在一個目錄中。在你的Java web server裡面配置一個應用, 譬如叫做:licenceCenter以Resin為例子:在httpd.conf裡面加上一下代碼:
| <web-app id="demo" app-dir="E:/licencescenter/webapp"> <servlet-mapping url-pattern='*.jsp' servlet-name='com.caucho.jsp.JspServlet'/> </web-app> |
其中在你的這個應用中的web.xml檔案必須包含
| <servlet servlet-name="LicenceService" servlet-class="com.caucho.hessian.server.HessianServlet"> <init-param service-class="com.collegesoft.licence.LicenceService"/> <init-param api-class="com.collegesoft.licence.LicenceServiceStub"/> </servlet> <servlet-mapping url-pattern="/LicenceService" servlet-name="LicenceService"/> |
11. 常見問題
Q: 為什麼不直接在webService裡面載入好一個Class, 而是要在用戶端來用classLoader來裝載?
A: 很多的程式員問過我這個問題,其實很簡單, 你如果知道classloader的機制, 就知道假設你擴充login的執行個體用到你的另外一個對象, 譬如OnlineUser, 那麼要在webService裡面來裝載你的類, 我就必須擁有你這個類, 但是webservice裡面是不知道你未來是要用到什麼類的。Q:為什麼在redhat9上,訪問驗證中心會出現中文亂碼問題?A:是由於redhat9的預設字元集不為GBK的緣故。一般採用將命令export LANG=zh_CN.GBK加在resin服務開機檔案中。 13.關於作者OldJavaMan, 是一個Java的狂熱分子, 喜歡OpenSouce的東西, 無奈自己還要靠這個東西養家, 無法實現開源的做法, 期望有一天可以衣食無憂地編寫自己喜歡地程式, 並從中擷取自己的人生樂趣。