Java軟件如何加密

Java軟件如何加密

[導讀] 本文擬針對Java軟件的加密保護方法,其中綜合運用了多種加密技術,抗破解強度高;使用純軟件保護技術,成本低。

Java軟件由於Java語言面向對象和編譯成中間碼執行的特點,其在抗反編譯和反盜版方面顯得尤其脆弱,爲此,我們針對Java軟件的特點,綜合運用各種加密方法,探索設計出一個實用型Java軟件加密保護方法。

一、Java軟件加密基本思路

對於應用軟件的保護筆者從兩個方面進行考慮,第一是阻止盜版使用軟件,第二是阻止競爭對手對軟件反編譯,即阻止對軟件的逆向工程。

1、阻止盜版

在軟件運行時對自身存在的合法性進行判斷,如果認爲自身的存在和運行是被授權的、合法的,就運行;否則終止運行。這樣即使軟件可以被隨意複製,只要盜版用戶沒有相應的授權信息就無法使用軟件。

2、阻止反編譯

對編譯產生的Class文件加密處理,並在運行時進行解密,解密者無法對軟件進行反編譯。

二、Java軟件加密的總體流程

爲了保護用Java語言開發的軟件,我們設計並實現了一個實用、高強度的加密算法。以下稱需要保護的Java軟件爲“受保護程序”,稱對“受保護程序”進行加密保護的軟件爲“加密程序”。對軟件加密保護的流程如圖1所示。

Java軟件如何加密

三、加密算法分析設計

1、用戶信息提取器設計

爲了防止用戶發佈序列號而導致“一次發行,到處都是”的盜版問題,提取用戶機器中硬件相關的、具有唯一性的信息——用戶計算機的硬盤分區C的序列號,並要求用戶將此信息與用戶名一起返回,之後用“序列號生成器”根據用戶返回信息生成一個唯一合法的軟件註冊序列號發回用戶,用戶即可使用此號碼註冊使用軟件。

這個信息提取器使用Winclows 32彙編以一個獨立的小程序方式實現,程序代碼如圖2所示。

Java軟件如何加密

2、序列號生成器與序列號合法性判斷函數的設計

序列號生成器與序列號合法性判斷函數中運用RSA加密算法。在序列號生成器中是使用私鑰將用戶返回的信息(硬盤序列號,用戶名)進行加密得到相應的註冊序列號;在序列號合法性判斷函數中使用私鑰將用戶輸入的註冊序列號解密,再與(硬盤序列號,用戶名)進行比較,一致則調用程序裝載器將程序其他部分解密裝入內存,初始化刪環境並運行程序主體;否則退出。

RSA加密算法的實現需要使用大數運算庫,我們使用MIRACL大數庫來實現RSA計算,序列號生成器的主要代碼如下:

char szlnputString[]=”機器碼和用戶名組成的字符串”;

char szSerial[256]=[0];//用於存放生成的註冊碼

bign,d,c,m; //MIRACL中的大數類型

mip→IBASE=16; //以16進制模式

n= mlrvar(0); //初始化大數

d= mirvar(0);

c= mirvar(0); //C存放輸入的字符串大數

m= mlrva(o);

bytes to big( len, szlnputString,c);

//將輸入字符串轉換成大數形式並存入變量c中

cinstr(n,”以字符串形成表示的模數”);//初始化模數

cinstr(d,”以字符串形成表示的公鑰”)://初始化公鑰

powmod(c,d,n,m); //計算m=cdmod n

cotstr(m,szSerial);//m的16進制字符串即爲註冊碼

序列號合法性檢測函數的主要代碼如下:

char szlnputStringL]=”機器碼和用戶名組成的字符串”;

char szSerial[ 256]=”用戶輸入的序列號”

bign,e,c,m; //MIRACL中的大數類型

mip→IBASE=16; //以16進制模式

cinstr(m,szSerial); //將序列號的16進制轉成大數形式

cinstr(n,”模數n的字符串形式”);//初始化模數n

cinstr(e,”字符串形式的公鑰”);//初始化公鑰

if compare(m,n)==-1) //m<n時才進行解密
{
powmod(m,e,n,c);//計算m=me mod n

big_to _bytes(0,c,szSerial,0); //轉爲字符串

return lstrcmp( szlnputString,szSerial);

}

3、強耦合關係的設計

如果在序列號合法性檢測函數中簡單地使用圖3所示流程:

Java軟件如何加密

解密者可以使用以下幾種手段進行攻擊:

(1)修改“判斷合法性子函數”的返回指令,讓它永遠返回正確值,這樣可以使用任意的序列號,安裝/使用軟件。

(2)修改判斷後的跳轉指令,使程序永遠跳到正確的分支運行,效果和上一種一樣。

(3)在“判斷合法性子函數”之前執行一條跳轉指令,繞過判斷,直接跳轉到“正常執行”分支運行,這樣可以不用輸入序列號安裝/使用軟件。

爲阻止以上攻擊手段,筆者在程序中增加了“序列號合法性檢測函數”與程序其他部分“強耦合”(即增強其與程序其他部分的關聯度,成爲程序整體密不可分的一部分,一旦被修改程序將無法正常工作)的要求(見圖1),並且設置一個“完整性檢測函數”用於判斷相關的代碼是否被修改過。當然,基於同樣的原因,“完整性檢測函數”也必須與程序其他部分存在“強耦合”關係。

強耦合關係通過以下方式建立:

在程序其他部分的函數(例如函數A)中隨機的訪問需要強耦合的“序列號合法性檢測函數”和“完整性檢測函數”,在調用時隨機的選擇使用一個錯誤的序列號或是用戶輸入的序列號,並根據返回結果選擇執行A中正常的功能代碼還是錯誤退出的功能代碼,流程如圖4所示。

Java軟件如何加密

經過這種改進,如果破解者通過修改代碼的方式破解將因“完整性檢測”失敗導致程序退出;如果使用SMC等技術繞過“序列號合法性判斷函數”而直接跳至序列號正確時的執行入口,在後續的運行中,將因爲隨機的耦合調用失敗導致程序退出。破解者要破解軟件將不得不跟蹤所有進行了耦合調用的函數,這顯然是一個艱鉅的任務。

4、完整性檢測函數的設計

我們使用CRC算法算出需進行完整性檢測的文件的校驗碼,並用RSA加密算法的公鑰(不同於序列號合法性檢測中的公鑰/私鑰對)將其加密存放在特定的文件中,在檢測時先用CRC算法重新生成需進行完
整性檢測的文件的校驗碼,並用私鑰將保存的校驗碼解密,兩者相比較,相等則正常運行;否則退出。

5、程序加載器的設計

與編譯成機器碼執行的程序不同,Java程序只能由Java虛擬機解釋執行,因此程序加載器的工作包括:初始化Java虛擬機;在內存中解密當前要運行的class文件;使解密後的c:lass文件在虛擬機中運行,在
需要時解密另一個class文件。圖5是用於初始化JVM的代碼:

Java軟件如何加密

以上介紹了我們設計的針對Java軟件的加密保護方法,其中綜合運用了多種加密技術,抗破解強度高;使用純軟件保護技術,成本低。經筆者在Windows系列平臺上進行測試,運行穩定,效果良好。

在研宄開發過程中,我們還總結出加密保護軟件的一些經驗:

1、對關鍵代碼和數據要靜態加密,再動態解密執行;要結合具體的工作平臺使用反跟蹤/調試技術;

2、要充分利用系統的功能,如在Windows下使用DLL文件或驅動程序形式能得到最大的豐又限,可以充分利用系統具有的各種功能;

3、如果可能應該將關鍵代碼存放在不可禚複製的地方;

4、序列號要與機器碼等用戶信息相關以阻止鹽復布序列號;

5、加密流程的合理性比加密算法本身的強度更重要。

小知識之DLL文件

DLL是Dynamic Link Library的縮寫,意爲動態鏈接庫。在Windows系統中,從Windows3.x的後續版本起,大部分的系統DLL文件被存放在%SystemPath%Windows\System32文件夾中(systempath爲系統安裝根路徑)目錄下。DLL是一個包含可由多個程序同時使用的代碼和數據的庫。

發佈了32 篇原創文章 · 獲贊 10 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章