JAVA中文件加密與解密的AES和RSA加密算法相結(jié)合的實(shí)現(xiàn)

加密技術(shù)是電子商務(wù)中最主要的安全技術(shù)之一,加密方法的選取直接影響著電子商務(wù)活動(dòng)中信息的安全程度。由于JAVA一開始就是面向網(wǎng)絡(luò)應(yīng)用的,它十分重視數(shù)據(jù)的安全性,在JDKJ.1中就已可以支持DES加密技術(shù),因此JAVA在電子商務(wù)中得到了廣泛的應(yīng)用。下面我就給大家介紹在Java環(huán)境下如何使用AES和RSA加密算法對(duì)數(shù)據(jù)文件進(jìn)行加密和解密。

一、 JAVA中的數(shù)據(jù)加密技術(shù)

加密技術(shù)根據(jù)一般可以分為對(duì)稱加密技術(shù)和非對(duì)稱加密技術(shù)。對(duì)稱加密技術(shù)屬于傳統(tǒng)的加密技術(shù),它的加密和解密的密鑰是相同的,它的優(yōu)點(diǎn)是:運(yùn)算速度快,加密強(qiáng)度高,可以通過(guò)硬件方式來(lái)實(shí)現(xiàn),適合大批量數(shù)據(jù)的加密處理,它的缺點(diǎn)是:加密和解密由于使用相同的密匙,密匙的分發(fā)與保密比較困難,目前常用的對(duì)稱加密技術(shù)有DES、3DES和AES加密算法。

非對(duì)稱加密技術(shù)屬于現(xiàn)代加密技術(shù),它的加密與解密的密鑰是不相同的,一個(gè)是私鑰,一個(gè)是公鑰,它的特點(diǎn)是:加密強(qiáng)度比較小,加密的速度比較慢,常用于數(shù)字簽名和加密密鑰,目前使用的非對(duì)稱加密技術(shù)主要有RSA和ECC加密算法,其中1024位的RSA是目前使用最為廣泛的非對(duì)稱加密技術(shù)。

JAVA語(yǔ)言的安全性是十分出色的,在JAVA中通過(guò)“Sun-JCF”提供對(duì)各種加密技術(shù)的支持。在JAVA還可以安裝其它公司的加密包,使用“SunjCF”所不支持的其它加密算法。早在JDKl.l中就已支持DES數(shù)據(jù)加密技術(shù),在JDKl.5中支持DES、3DES、AES等對(duì)稱加密技術(shù),在非對(duì)稱加密技術(shù)方面支持RSA技術(shù)。

二、 JAVA中的數(shù)據(jù)加密類

(1)KeyGenerator類用于獲得各類對(duì)稱加密技術(shù)的密鑰,主要的方法有:

getlnstance(“加密算法字符串”),用于設(shè)置要獲得的密鑰的加密算法

init(),用于初始化對(duì)稱加密的密鑰對(duì)象

generateKey(),從對(duì)稱加密的密鑰對(duì)象中取得密鑰

(2)KeyPairGenerator類用于獲得非對(duì)稱加密技術(shù)的密匙,主要的方法有:

getlnstance(“非對(duì)稱加密算法字符串”),用于設(shè)置要獲得的密鑰的加密算法

initialize(密鑰長(zhǎng)度),用于初始化非對(duì)稱加密的密鑰對(duì)象

generateKeyPair(),返回非對(duì)稱密鑰組對(duì)象

getPublic(),從非對(duì)稱密鑰組中取得公鑰

geLPrivate(),從非對(duì)稱密鑰組中用于取得私鑰

(3)Cipher類是JAVA加密的主要類,用于按一定的算法對(duì)數(shù)據(jù)文件進(jìn)行加密、解密、包裝和返包裝。主要的方法有:

getInstance(“加密算法字符串”),用于設(shè)置要使用的加密算法

Init(“類型”,密匙),按提供的類型和密匙初始化加密對(duì)象

getBLockSize(),用于返回加密算法的輸入分組長(zhǎng)度

getOutputSize(),用于返回加密算法的輸出分組長(zhǎng)度

update(inBytes,blockSize,outBytes),對(duì)inBytes進(jìn)行加密或解密處理,并將處理結(jié)果輸出到outBytes中

doFinal(),對(duì)要不足分組長(zhǎng)度的數(shù)據(jù)進(jìn)行填充處理

三、JAVA中如何實(shí)現(xiàn)AES和RSA加密算法相結(jié)合的數(shù)據(jù)文件的加密和解密

根據(jù)我們上面介紹的有關(guān)對(duì)稱加密技術(shù)和非對(duì)稱加密技術(shù)的分析,現(xiàn)在我們一般采用對(duì)稱加密技術(shù)和非對(duì)稱加密技術(shù)相結(jié)合的方法來(lái)給文件加密。下面我們利用AES(對(duì)稱加密技術(shù))加密數(shù)據(jù)文件,利用RSA(非對(duì)稱加密技術(shù))加密AES加密密鑰,這樣即可以提高加密的速度,又可以解決AES密鑰自身的安全性。由于數(shù)據(jù)文件進(jìn)行了加密,因此可以通過(guò)普通的電子郵件系統(tǒng)完成加密文件的傳輸。AES和RSA相結(jié)合的數(shù)據(jù)文件加解密過(guò)程如下:

(1)接受方:生成1024位的RSA密鑰對(duì),然后通過(guò)電子郵件向發(fā)送方發(fā)送自己的公鑰數(shù)據(jù)。

(2)發(fā)送方:第一步通過(guò)電子郵件取得接受方的RSA公鑰數(shù)據(jù);第二步隨機(jī)生成AES密鑰;第三步用獲得的RSA公鑰和RSA加密算法加密AES密鑰并將加密后的AES密鑰寫人數(shù)據(jù)文件的頭部;第四步用AES密鑰和AES加密算法給數(shù)據(jù)文件加密,并將加密后的數(shù)據(jù)文件寫入數(shù)據(jù)文件的尾部;最后通過(guò)電子郵件,以附件的形式將數(shù)據(jù)文件發(fā)送給接收方。

(3)接收方:第一步從接受到的郵件的附件中讀取加密后的AES密鑰;第二步用自己的私鑰和RAS加密算法解密AES密鑰;第三步接著從接受到的郵件的附件中讀取加密數(shù)據(jù)文件,用于解密的AES密鑰和ASE加密算法解密加密數(shù)據(jù)文件,并將解密后的數(shù)據(jù)寫入數(shù)據(jù)文件。

2、如何在JAVA中實(shí)現(xiàn)AES和RSA加密算法相結(jié)合的數(shù)據(jù)文件加密和解密過(guò)程

具體源程序如下:

import java.io.*;

lrnport Java.security.*;

lmport Javax.cIypto.*;

impon javax.crypto.spec.*;

public class Aes_Rsa_ Encrypt

{

public static void inain(String[] args)

{

try

{

if(args[O].equals(”-g””//生成RSA密鑰對(duì)

{

KeyPairGenerator keyGen=KeyPairGenerator.getln8tance("RSA");

SecureRandom random=new SecureRandom();

keyGen.initialize(1024,random);

KeyPair keypair = keyGen.generateKeyPair();

ObjectOutputStream out =new ObjectOuLputStream(new FileOut-putStream (l'pub_key"));

out.writeObject(keypair,getPublic());

out.close();

out =new ObjectOutputStream (new FileOutputStream C"pri_key"));

out.writeObject(keypair.getPrivate());

out.close();

}

else if(args[O].equals(" -e")) //對(duì)指定的數(shù)據(jù)文件進(jìn)行加密處

{

KeyGenerator keyGen = KeyGenerator.getlnstance("AES");

keyGen.init(128);

SecretKey key=keyGen.generateKey(),

ObjectlnputSUeam keyln =new ObjectlnputStream (new Fileln-putStream ("pub_key"));

Key publicKey=(Key)keyln.readObject();

keyln.close();

Cipher cipher=Cipher.getlnstance("RSA");

cipher.init(Cipher.WRAP_MODE,publicKey);

byteo wrappedKey=cipher.wrap(key);

DataOutputStream out=new DataOutputStream (new FileOutput-Stream(args[2]));

out.writelnt(wrappedKey.length);

out.write(wrappedKey);

InputStream in=new FilelnputStream(args[l]);

cipher=Cipher.getlnstance("AES");

cipher.init(Cipher.ENCRYPT_MODE,key);

crypt(in.out,cipher);

in.close();

out.close();

}

else if(args[Ol.equals("-d")])

{

DatalnputStream m =new DatalnputStream (new Filelnput-seam(rugs[i]));

int length=in.readlnt();

byteo wrappedKey=new bytepengthj;

in.read(wrappedKey,O,length);

ObjectlnputStream keyln =new ObjectlnputStream (new Fileln-putStream C'pri_key"));

Key privateKey=(Key)keyln.readObject();

keyln.close();

Cipher cipher=Cipher.getlnstance("RSA");

cipher.init(Cipher.UNWRAP_MODE,privateKey);

Key key =cipher.unwrap (wrappedKey,"AES",cipher.SE-CRET_KEY);

OutputStream out=new FileOutputStream(args[2]);

cipher=Cipher.getlnstance("AES");

cipher.init(CipherDECRYPT_MODE,key);

crypt(in,out,cipher);

in.close();

ouLclose();

}

}

catch (IOException exception)

{

exception.printStackTrace0;

}

catch (GeneraISecurityException exception)

{

exception.printStackTrace0;

}

catch (ClassNotFoundException exception)

{exception.printStackTrace0;

}

}

public static void crypt(lnputStream in,OutputStream out,Ciphercipher) throws IOException,GeneralSecurityException ii自己定義的

{

int blockSize=cipher.getBlockSize0;

int outputSize=cipher.getOutputSize(blockSize);

byte[] inBytes=new byte[blockSize];

byteU outBytes=new byte[outputSize];

int inLengtb=0;

boolean more=true;

while(more)

{ inLength=in.read(inBytes);

if(inLength==bjockSize)

{

int outLength=cipher.update(inBytes,O,blockSize,outBytes);

out.write(outBytes,O,outLength);

}

else

outBytes=c:ipher.doFinal0;

out.write(outBytes);

}

public static fmal int KEYSIZE=1024;

}

本程序可以完成RSA密鑰的生成、數(shù)據(jù)文件加密和數(shù)據(jù)文件解密。運(yùn)行前用iavac進(jìn)行對(duì)Aes_Rsa_ Encrypt.java文件進(jìn)行編譯,然后按如下方法執(zhí)行:

(1)生成RSA加密算法的密鑰文件(文件名為pri_key)和公鑰文件(文件名為pub_key)

java Aes_Rsa_Encrypt-g keyfile

(2)對(duì)指定的數(shù)據(jù)文件中的內(nèi)容進(jìn)行加密,并將結(jié)果寫出入指定的加密文件

java Aes_Rsa_Encrypt-e _ 數(shù)據(jù)文件名 _ 加密文件名

(3)對(duì)指定的加密文件中的內(nèi)容進(jìn)行解密,并將結(jié)果寫出入指定的解密文件

java Aes_Rsa_Encrypt-d _ 加密文件名 _ 解密文件名

本程序在JDKl.5下測(cè)試通過(guò)。

用JAVA來(lái)實(shí)現(xiàn)AES和RSA加密算法相結(jié)合的數(shù)據(jù)文件加密與解密方法非常的簡(jiǎn)便,您可以通過(guò)以上的方法操作試一下。

小知識(shí)之公鑰

公鑰是與私鑰算法一起使用的密鑰對(duì)的非秘密一半。公鑰通常用于加密會(huì)話密鑰、驗(yàn)證數(shù)字簽名,或加密可以用相應(yīng)的私鑰解密的數(shù)據(jù)。公鑰和私鑰是通過(guò)一種算法得到的一個(gè)密鑰對(duì)(即一個(gè)公鑰和一個(gè)私鑰)其中的一個(gè)向外界公開,稱為公鑰;另一個(gè)自己保留,稱為私鑰。通過(guò)這種算法得到的密鑰對(duì)能保證在世界范圍內(nèi)是唯一的。使用這個(gè)密鑰對(duì)的時(shí)候,如果用其中一個(gè)密鑰加密一段數(shù)據(jù),必須用另一個(gè)密鑰解密。比如用公鑰加密數(shù)據(jù)就必須用私鑰解密,如果用私鑰加密也必須用公鑰解密,否則解密將不會(huì)成功。