java誕生於1995年,是一門較年輕的語言。它以平台無關性,安全性,面向對象,分布式,鍵壯性等特點贏得了眾多程序員的青睐。特別是它簡潔的面向對象的語言風格,更讓許多人對它愛不釋手。但人們在使用java的過程中,會發現它有幾個致命的弱點:運行速度慢,用戶使用不便,源代碼保護機制不夠安全。特別是在保護源代碼方面,java是基於解釋一種叫java字節碼的中間代碼來運行其程序的,而且jvm比計算機的微處理器要簡單的多,文檔也很齊全,結果造成其目標程序很容易被反編譯,而且所得代碼和其原始代碼十分相似,甚至可以一模一樣,可讀性相當好。這就給java的代碼保護帶來了不利。但要實現java程序的保護,也不是不可能的,經研究和總結,至少有三種實現方式:1.混淆器;2.網絡加載重要類;3加密重要類。
1 混淆器
目前,開發人員使用的比較多的保護代碼的方法是用混淆器。混淆器是采用一些方法將類,變量,方法,包的名字改為無意義的字符串;使用非法的字符代替符號;貼加一些代碼使反編譯軟件崩潰;貼加一些無關的指令或永遠執行不到的指令等使反編譯無法成功或所得的代碼可讀性很差。這樣就實現了反反編譯的目的。我們來做個演示。原始代碼如下:
import java.io.*;
import java.security.*;
public class sKey_kb{
public static void main(String args[]) throws Exception{
FileInputStream f=new FileInputStream("key1.dat");
ObjectInputStream b=new ObjectInputStream(f);
Key k=(Key)b.readObject();
byte[] kb=k.getEncoded();
FileOutputStream f2=new FileOutputStream("keykb1.dat");
f2.write(kb);
for(int i=0;i<kb.length;i++){
System.out.print(kb[i]+",");
} } }
使用混淆器後,再用jad反編譯得代碼如下:
import java.io.*;
import java.security.Key;
public class sKey_kb{
public skey() {}
public static void main(String args[]) {
FileInputStream fileinputstream=new FileInputStream(ma);
ObjectInputStream objectinputstream=new ObjectInputStream(fileinputstream);
Key key=(Key)b.readObject();
byte abyte0[]=key.getEncoded();
FileOutputStream fileoutputstream=new FileOutputStream(na);
fileoutputstream.write(abyte0);
for(int i=0;i<abyte0.length;i++)
System.out.print(abyte0[i]+oa);
}
private static String a(String s){
int i=s.length();
char ac[]=new char[i];
for(int j=0;j<i;j++) ac[j]=(char)(s.charAt(j)^0xffff5aca);
return new String(ac);
}
private static String ma="u5AA1u5AAFu5AF3u5AFBu5AE4u5AAEu5AABu5ABE";
private static String na="u5AA1u5AAFu5AB3u5AA1u5AA8u5AFBu5AE4u5AAEu5AABu5ABE";
private static String oa="u5AE6";
public static{
ma=a(ma);
na=a(ma)
oa=a(oa);
} }
混淆後,再反編譯所仍然能得到源代碼,但顯然,所得代碼與原始代碼比,變得難以讀懂,代碼中多了其他的方法,文件名等信息也被打亂了。並且,把以上代碼寫進sKey_kb.java中,無法通過編譯。
但是,如果在編寫軟件時,在軟件中寫入某些注冊信息,或一些簡單的算法,通過反編譯,還是有可能得到這些信息的,從而未能達到保護軟件的目的。反編譯器與混淆器之間的斗爭是永無止盡的。所以從其他角度去保護java的源代碼是很有必要。
2 網絡加載重要類
在java中提供了一個ClassLoader類,這個類可以讓我們使用類加載器將所需要的java字節碼文件加載到jvm中。我們通過重寫這個類,可以實現從網絡通過url加載java字節碼文件。這樣,我們就可以把一些重要的,隱秘的class放在網絡服務器上,通過口令去檢驗是否有權限下載該類。從而實現java代碼保護的目的。其次在java中正好提供了URLClassLoader這個類,通過此類,正好可以實現我們的目的。URLClassLoader類的基本使用方法是通過一個URL類型的數組告訴URLClassLoader類的對象是從什麼地方加載類,然後使用loadclass()方法,從給定的URL中加載字節碼文件,獲得它的方法,然後再執行。
具體步驟如下:
1.創建URL
URL url[]={
new URL("file:///c:/classloader/web"),
new URL("http://http://www.ddvip.com/")
};
2.創建URLClassLoader對象