Java代碼加密技術如何用基于TripleDES加密算法和RSA加密算法來實現(xiàn)

Java語言是一種應用廣泛的編程語言,再加上其平臺無關性的特點,如果不對Java語言編寫的軟件進行相應的加密處理,軟件源代碼就很容易被一些居心叵測的人竊取,造成軟件內容泄露。為此,我們運用經典的加密算法Trple DES對Java源文件編譯后生成的類文件進行加密,然后對JVM的類裝載器進行改造,使其能夠識別加密后的類文件,同時為了提供更高程度的加密,利用RSA算法對前一加密階段生成的密鑰進行加密,最終達到真正保護軟件版權等目的。

一、Java代碼加密技術

對于Java代碼,一般有以下幾種加密方法:

1、Java代碼模糊處理

代碼模糊處理字面上的意思就是模糊處理代碼的行為,Java模糊處理器用不易察覺的方法改變程序,以至于它的運行對JVM來說是一模一樣的,但它使得試圖理解程序的人更加迷惑了。一種常用的模糊處理代碼的方法是用一個非法的字符串來替代類文件中的標記,這比使用沒有意義的字符串具有更好的模糊處理效果。然而,可以修改反編譯器,使之能夠處理這些模糊類文件。所以僅僅依賴‘模糊類文件’來保證代碼的安全是不夠的。

2、對源文件進行加密

比如PGP(Pretty Good Privacy)或GPG((NU Privacy Guard)。用戶在應用之前必須先進行解密,但是解密后用戶就得到了一份不加密的文件,相當于事先沒有加密,所以這種技術稱之為保密更為合適。

3、加密類文件(.class文件)

因為Java代碼被編譯為類文件,然后由JVM加載類文件,把它轉換為二進制機器碼。因此可以對編譯后形成的類文件進行加密,JVM用定制的類裝載器(ClasfLoader)解密文件。JVM每次裝入類文件時都需要一個稱為ClasLoader的對象,這個對象負責把新的類裝入正在運行的JVM。JVM給Clas9Joader一個包含了待裝入類名字的字符串,然后由ClasLoader負責找到類文件,裝入原始數(shù)據(jù),并把它轉換成一個Class對象。用戶下載的是加密過的類文件,在加密類文件裝入之時進行解密,因此可以看成是一種即時解密器。由于解密后的字節(jié)碼文件永遠不會保存到文件系統(tǒng),所以竊密者很難得到解密后的代碼。

在此,我們選取第三種加密技術,并利用Trple DES (3DES)算法,對類文件進行加密。

二、TripleDES加密算法

DES加密算法為密碼體制中的對稱密碼體制,如圖2所示。其密鑰長度為56位,明文按64位進行分組,將分組后的明文組和56位的密鑰按位替代或交換的方法形成密文組的加密方法。

DES工作的基本原理是,其入口參數(shù)有三個:keydata、mode、key為加密解密使用的密鑰,data為加密解密的數(shù)據(jù),mode為其工作模式。當模式為加密模式時,明文按照64位進行分組,形成明文組,key用于對數(shù)據(jù)加密,當模式為解密模式時,key用于對數(shù)據(jù)解密。實際運用中,密鑰只用到了64位中的56位,這樣才具有高的安全性。

3DES是DES加密算法的一種模式,它使用3條64位的密鑰對數(shù)據(jù)進行三次加密。比起DES,3DES更為安全。3DES是DES向AES過渡的加密算法,是DES的一個更安全的變形。它以DES為基本模塊,通
過組合分組方法設計出分組加密算法,其具體實現(xiàn)如下:設Ek()和Dk()代表DES算法的加密和解密過程,K代表DES算法使用的密鑰,M代表明文,S代表密表,則:

3DES加密過程為:S=Ek3 (Dk2 (Ekl (M)))。

3DES解密過程為:M =Dkl((EK2 (Dk3(S)))。

Java加密擴展即Java Cryptograp hy Exten SiDn,簡稱JCE。它是Sun的加密服務軟件,包含了加密和密匙生成功能。JCE是JCA(Java Cryptography Architecture)的一種擴展。

JCE沒有規(guī)定具體的加密算法,但提供了一個框架,加密算法的具體實現(xiàn)可以作為服務提供者加入。除了JCE框架之外,JCE軟件包還包含了SunjCE服務提供者,其中包括許多有用的加密算法,比如DES和RSA等常用加密算法。在實際的應用當中,需要下載相應的.jar文件可到http://www. bouncycastle. org下載bcpIOv - jdk14 - 123. jar)。運用3DES算法加密解密的大致步驟如下:

生成密鑰:

//生成一個可信任的隨機數(shù)源

SecureRandjom dataSrc=naA/ SecureRandanl():

//為我們選擇的3 DES算法生成一個KeyGenerator對象

KeyGenerabr keyGene =KeyGenerabr. getjnstance("DES");

Kg. init (dataSn:) ;

//生成密鑰

Secret Key key=keyGene. geneniteKey();

//將密鑰數(shù)據(jù)保存為文件供以后使用,其中keyFile.h tn l為保存的文件

Util.writeFile (keyFile. htnl. key. getEncoded());

加密數(shù)據(jù):

//產生一個可信任的隨機數(shù)源

SecureRandom dataSrc=new SecureRandom();

//從密鑰文件keyFile. hml中得到密鑰數(shù)據(jù)

Byte ke)Data=UtiL readFile (keyFile. htnD;

//從原始密鑰數(shù)據(jù)創(chuàng)建DESKeySpec對象

DESKeySpec dkspec=newDESKeySpec(rawKe)Data);

//創(chuàng)建一個密鑰工廠,然后用它把DESKeySpec轉換成Secret Key對象

Secre tKeyFactory keyFac =Secre tKeyFactorry. getln stance ( "DES" ) ;

Secret Key key = keyFac. generateSecret( dkspec ) ;

//Cipher對象實際完成加密操作

Cipher cipher=Cpher. getlnstance(”DES”);

//用密鑰初始化Cipher對象

cpher. init( Cipher. I:NCRYPT_MODE, key, dataSrc);

//通過讀類文件獲取需要加密的數(shù)據(jù),unEnc ryp tFile為需要加密的明文文件名

Byte data=Util. readFile (unEncryptFileName);

//執(zhí)行加密

Byte encryptedClassData=cpher. doFinal(data);

//保存加密后的文件,覆蓋原有的類文件。

U til.w riteFile(unEnc ryp tFilename,

encryp tedClasData);

解密數(shù)據(jù):

//生成一個可信任的隨機數(shù)源

Secun:Random dataSrc=new SecureRandom();

//從密鑰文件中獲取原始密鑰

Byte ke}Dam=UtiL readFile( keyFile. htnl);

//創(chuàng)建一個D ESKeySpec對象

DESKeySpec dkspec=new DESKeySpec(ke}Data);

//創(chuàng)建一個密鑰工廠,然后用它把D ESKeySp ec對象轉換成Secret Key對象

SecretKeyFacn)ry key Fac=SecretKeyFacbry getlnstance(”3DES");

SecretKey key=keyFac. generateSecret( dkspec);

//Cip he r對象實際完成解密

Cpher cipher=Cipher. getlnstance(”3DES”);

//用密鑰初始化Cipher對象

Cipher. init( Cipher.DECRYPT MODE, key, dataSrc);

//獲得經過加密處理的數(shù)據(jù)

Byte encrypkdData=Util. readFile (unEncryp tFilenane);

//執(zhí)行解密

Byte decryptedData=cipher. doFinal(encryp tedD ata;

//然后將解密后的數(shù)據(jù)轉化成原來的類文件。

3DES加密算法對文件的加密解密工作具體流程圖見圖3,其中K1,K2,K3為3條64位的密鑰。由于JVM都有一個默認的類轉載器(ClasLoader)用來裝載類文件,如果由默認的Classlader尋找經過加密的類文件,由于類文件已經加密,所以它不會認可這個類文件,裝入過程將失敗。因此,我們必須自己實現(xiàn)C1assLoader,然后將上述代碼與自定義的類裝載器結合起來,就可以變解密便運行,從而實現(xiàn)保護代碼的作用。然而,因為對稱式的加密方法如果是在網絡上傳輸加密文件就很難把密鑰告訴對方,不管用什么方法都有可能被別竊聽到。因此,如果3DES加密算法的密鑰在傳輸過程中泄漏,那么竊取者就可以用這個密鑰解密,得到類文件的明文,然后用Java反編譯類文件就可以得到Java源文件,從而使所有的加密工作失效。

同時,如果竊取者對類裝載器進行修改,使其將解密后的類文件保存到一文件處而非立即運行,然后反編譯保持下來的解密后的類文件,就得到了Java源文件,同樣使得加密工作失效。但是這些都有一個前提,那就是竊取者得到了密鑰。因而對密鑰的加密工作就很的重要。在此采用非對稱經典的非對稱加密RSA算法。

三、RSA加密算法

RSA加密算法屬于非對稱加密算法。與對稱加密算法不同,非對稱加密算法需要兩個密鑰:公開密鑰(publickey)和私有密鑰(privatekey)。公開密鑰與私有密鑰是一對,如果用公開密鑰對數(shù)據(jù)進行加密,只有用對應的私有密鑰才能解密;如果用私有密鑰對數(shù)據(jù)進行加密,那么只有用對應的公開密鑰才能解密。因為加密和解密使用的是兩個不同的密鑰,所以這種算法叫作非對稱加密算法。非對稱式的加密方法的公鑰是可以公開的,不怕別人知道,收件人解密時只要用自己的私鑰即可,這樣就很好地避免了密鑰的安全性問題。

非對稱加密算法實現(xiàn)機密信息交換的基本過程是:甲方生成一對密鑰并將其中的一把作為公用密鑰向其他方公開;得到該公用密鑰的乙方使用該密鑰對機密信息進行加密后再發(fā)送給甲方;甲方再用自己保存的另一把專用密鑰對加密后的信息進行解密。甲方只能用其專用密鑰解密由其公用密鑰加密后的任何信息。

非對稱加密算法消除了最終用戶交換密鑰的需要,保密性好,但加密和解密花費時間長、速度慢,只適用于對少量數(shù)據(jù)進行加密,因此在這里采用經典的非對稱加密RSA算法對3DES算法生產的密鑰進行加密。

RSA方法的工作原理如下:

(1)任意選取兩個不同的大質數(shù)p和q,計算乘積r=p×q。

(2)任意選取一個大整數(shù)e,e與(p-1)×(q-l)互質,整數(shù)e用做加密密鑰。注意:e的選取是很容易的。

例如,所有大于p和q的質數(shù)都可用。

(3)確定解密密鑰d:dXe=Imod(p -1)x(q -1);根據(jù)e、p和q可以容易地計算出d。

(4)公開整數(shù)r和e,但是不公開d。

(5)將明文P(假設P是一個小于r的整數(shù))加密為密文C,計算方法為C=Pe mod r(e為冪次方)。

(6)將密文C解密為明文P,計算方法為P=Cd mod r(d為冪次方)。

然而只根據(jù)r和e(不是p和q)要計算出d是不可能的。因此,任何人都可對明文進行加密,但只有授權用戶(知道d)才可對密文解密。所以RSA方法可以具有很好的加密效果。

利用RSA加密算法加密解密的大致步驟如下:

File testFile=nev File(”test.html“);

//test.html為需要加密的明文

//讀入明文

File hputStrean in=new FilelnputStream(file);

ByteArnUJOuputStrean out=new

B yteA na}OuputStream();

byte[]temptbuf=new byte[1024];

int count=0:

while((count=in.read(temptbuf))!=-1)(bout write( temptbut O,count);

temptbuf=new byte[1024];

}

in.clo se();

byte[]data=ouL tnByteArray();

//將明文轉換成字節(jié)數(shù)組保存在data中

KeyPair keyPair = RSAUtiL generateKeyPair() ;

//生成密鑰對

RSAPublicKeypub_key =RSAPublicKey) keyPair. getPublic () ;

R SAPrivateKey p ri_key =(RSAPrivateKey) keyPair. getPrivate () ;

byte[ ] modBytes =pubKey. geModulus() .tobyteA rray () ;

byte[ ] pubExpByks =pubKey. ge tPublicExponent() . roB yteA nay ( ) ;

byte[ ] prModBytes =priKey. ge Modulus().dByteA rray();
byte[]priExpBytes=p riKey. ge tPrivateExponent().bB yteA nay();

//生成公鑰

RS4PublicKey pubKey=R SAUtiL genemteR SA PublicKey (pul:Mo dB ytes,pubExpB yteS);

//生成私鑰

RSAPrivateKey p riKey=R SAU tiL generateRSAPrivateKey(p rModB ytes,p riExpB ytes);

byte[]tempt=RS4Util. encr)pt(pubKey, data);

//用公鑰對data中的明文數(shù)據(jù)加密得到密文testFile=new File(" encOrpt_result html”);

OuputStrean out=nav FileOuputStrefm(testFile);

//將密文存放在enc ryp t_n: sult.htul文件中

ouL write( tempt);

out.cbse();

byte[]data=RStYUtiL decO,pt(priKey, tanpt);

//用私鑰對tempt中的密文解密得到明文

testFile=nav File(”decWpt_n:sult- hhil");

out=new FileOutputStI℃an(testFile);

out.w rite( data);

//將解密后得到的明文存儲在dec r3rp t_re sult html文件中

out flush () ;

out close () ;

}

RSA加密算法對密鑰的加密解密的具體工作流程如圖4所示。

至此,一個基于Triple DES和RSA加密算法的Java代碼加密技術就完成了。利用加密解密技術是保證數(shù)據(jù)傳輸中數(shù)據(jù)安全性的一種常用的方法,Java語言由于其平臺無關的特性,且應用十分廣泛,因此保證安全性就顯得特別的重要。利用3DES算法生產一個密鑰對編譯過后的類文件進行加密,再利用RSA算法對獲得的密鑰進行加密,在很大程度上可以保證Java源代碼的安全性。整個加密解密的工作流程圖如圖5所示。

目前該技術已經實際運用在廣州中間件研究中心的各種軟件產品當中,很好的保護了該中心的軟件版權的安全。

小知識之Triple DES加密算法

Triple DES加密算法又被稱作3DES加密算法,它相當于是對每個數(shù)據(jù)塊應用三次DES加密算法。由于計算機運算能力的增強,原版DES密碼的密鑰長度變得容易被暴力破解;3DES即是設計用來提供一種相對簡單的方法,即通過增加DES的密鑰長度來避免類似的攻擊,而不是設計一種全新的塊密碼算法。