Java加密和licence控制的設計

1.版權聲明

    本文是關於如何通過序列號來加載加密的class文件的闡述。
   本文所提及的Resin hessian是Caucho公司的註冊產品名稱, 其版權規caucho所有。
本文可以轉載, 但是必須註明作者的Blog地址:

2. 本文的適用對象

    作爲技術人員,本文的技術細節涉及到Java語言的基礎知識, 您在閱讀前應該瞭解Java動態裝載Class的機制,以及常規的Java加密的相關知識, 同時本文假定您已經具有開發web的基本能力, 瞭解jsp和servlet的運作過程。

3.怎樣閱讀

你可以在下面地址下載到本文所用到的Jar文件和加密工具
加密工具的下載:
關於序列號的生成部分, 鑑於保護公司產品的考慮就不再公開發布了, 有興趣的同仁可以用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的東西, 無奈自己還要靠這個東西養家, 無法實現開源的做法, 期望有一天可以衣食無憂地編寫自己喜歡地程序, 並從中獲取自己的人生樂趣。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章