天津工業大學計算機科學與軟件學院 李夢濤
在Java的編譯過程中不將變量和方法等符號的引用轉換為數值引用,也不確定程序執行過程中的內存狀態,只是將這些符號的引用信息保留在類文件中,由解釋器在運行過程中創建內存布局,然后再通過查找表來確定一個變量或方法所在的地址。Java源代碼不像C/C++源代碼一樣被編譯成二進制機器碼,編譯Java源代碼會生成中間字節碼,是一種與平臺無關的源代碼的表示方式。字節碼在加載后可以被解釋或編譯,這就產生了高級編程語言到底層機器代碼之間的兩步變換。是這一中間步驟使得反編譯Java字節碼得到的源代碼近乎完美。字節碼攜帶了在源文件中可以找到的所有重要信息。盡管注釋和格式丟失了,但所有的方法、變量和編程邏輯都完好的保留下來,由于字節碼不表示最底層機器語言,因此代碼的格式非常類似于源代碼。
Java類文件不是真正的二進制文件,而是一種有格式的中間代碼,這就給反編譯Java類文件提供了可能。反編譯得出的代碼具有很高的質量,基本上可以完全反映編寫者的思路,這樣一來,軟件開發商和軟件開發人員投入大量精力和艱苦努力編寫的源代碼就很容易被黑客竊取,軟件中包含的重要算法也會泄露出去。因此Java應用程序也就毫無保密性可言,Java軟件在知識產權的保護上面臨著很大的安全風險。
目前的Java軟件的保護方法大多是基于單機應用的研究,傳統的Java軟件保護方法主要有本地化技術、遠程接口訪問技術、軟件數字水印技術以及混淆技術,其中軟件數字水印技術和混淆技術是目前研究、應用較多,受到廣泛關注的技術。
Java本地化,是指通過將Java應用程序編譯成本地應用程序來達到增加反編譯的難度,實現軟件保護的方法。實現步驟如下:首先編寫Java源代碼,然后通過Java編譯器將Java源代碼編譯成Java類文件,最后使用本地編譯工具將Java類文件編譯成二進制的本機應用程序。本地化技術雖然能夠很好的保護Java類文件,使其達到與傳統的用C/C++等語言開發的軟件一樣的安全強度,但也存在一些問題:本地化技術能夠為較簡單的單戶機應用軟件提供較高水平的保護,其反編譯的難度與傳統的C/C++開發的軟件相同,但還無法對復雜的應用軟件提供全面的保護,也無法保護B/S結構的應用軟件,此外,要準確的診斷和定位本機編譯產生的Java應用程序中出現的問題也是十分困難。雖然目前發展還很不成熟,但卻是Java領域一項廣受關注的技術。實踐和理論己經證明,對于某些應用軟件和使用環境,本地化技術不失為一種優秀的解決方案。
分布式結構是現代軟件開發中廣泛采用的一種體系結構,通常將軟件分為客戶端和服務器端,核心的功能模塊和業務流程都部署在服務器端為客戶端提供服務,客戶端負責采集數據、提交服務請求和與服務器端通信,這種體系結構的采用可以提高系統的可移植性和互操作性,大幅度降低軟件的開發成本。遠程接口訪問技術能有效地保護關鍵的Java類文件,從而達到軟件保護的目的。但是這種方式也存在著明顯的局限性和很大的安全隱患:遠程接口訪問技術實際上是將保護的焦點從關鍵的類文件轉移到了應用服務器上。在這種體系結構下,制定完善的安全機制來保護端口至關重要,因為如果應用服務器被攻破,那么所有部署在服務器上的服務模塊和類文件就完全暴露在攻擊者面前,后果不堪設想。
軟件數字水印是眾多數字水印的一種,它的主要保護對象是計算機代碼,包括源代碼和機器碼。使得它們免于或者減少遭受非法復制和非法篡改的危險,由于計算機代碼是不能容忍任何錯誤的,因此一些傳統的利用可允許錯誤范圍內修改計算機程序從而嵌入水印的方法將不適用于計算機軟件。軟件數字水印技術也存在一些不足,比如:需要插入額外的代碼,需要仔細地編寫函數及其調用,否則容易被有經驗的反編譯者識破,從而擦除水印。另外,靜態軟件數字水印算法的健壯性相對較差,而動態軟件數字水印算法雖然具有很好的健壯性,但是它只能保護整個應用程序,而不能保護某一部分特定的代碼,同時,動態軟件數字水印的檢測方式令它的某些應用受到限制。目前的水印算法在提供可靠的版權證明方面或多或少都有一些的尚不完善的地方,因此尋找能提供完全可靠版權保護的軟件數字水印算法成為一個重要的課題。軟件數字水印的用途主要有以下幾個方面:作為侵犯知識產權的證據;發現被剽竊的程序;追蹤非法拷貝的源頭。
代碼混淆技術是目前比較成熟和流行的一種軟件保護技術。代碼混淆技術是對類文件進行代碼語義、程序流程和邏輯結構的重新組織,代碼混淆并不能增加反編譯的難度,使用反編譯器仍然可以對混淆后的類文件進行反編譯,得到代碼,但此時的代碼是經混淆后的代碼,可讀性已經大大降低,難以從代碼中發現源代碼的編寫思路和關鍵算法,從而達到保護軟件的目的。混淆是一個相對安全的過程,可以完整地保留應用程序的功能。但某些情況下,混淆程序所執行的變換也可能會影響程序的正常運行。如:動態類加載的問題、反射問題、串行化問題和違反命名慣例的問題,這些問題雖然較少出現,但卻會影響程序的正常執行,另外,混淆技術的應用使得維護應用程序和排除故障變得更加困難,有時甚至是不可能的。Java異常事件處理是隔離有缺陷代碼的一種有效方式,而查看堆棧跟蹤一般可以告訴用戶何處出錯以及出什么錯。為源代碼文件名和行編號保留調試信息,保證運行時可以報告出錯代碼的準確位置。混淆程序可能會禁止這一特性并使調試變得困難,因為開發人員只能看到被混淆的類名稱而不是真正的類名稱和行編號。
目前己經有很多針對Java軟件的保護方法,在一定程度上起到了保護Java軟件的作用,但是這些方法都有各自的局限性和不足。Java軟件的知識產權保護問題也遭遇了非常大的挑戰,許多廠商和個人投入大量人力物力開發的軟件被侵權,一些重要的算法和創新思想被抄襲。因此,研究針對Java軟件的保護方法已經迫在眉睫。
[1]申茜,辛曉輝.JAVA軟件面臨的風險及其保護[J].電腦知識與技術(學術交流),2007(23).
[2]胡燕京,張健,王海義,劉軼群.軟件保護研究及其在Java軟件保護中的應用[J].現代電子技術,2007(15).
[3]楊勇義.基于Android平臺的軟件保護技術研究[D].北京郵電大學,2012.
[4]霍建雷.用于Java軟件保護的代碼混淆技術研究與實現[D].西北大學,2009.