怎么样通过java加密RSA的工具?
鉴于rsa加密的重要性和相关源代码的匮乏,经过整理特此贴出。需要到http://www.bouncycastle.org下载bcprov-jdk14-123.jar。importjavax.crypto.Cipher;
importjava.security.*;
importjava.security.spec.RSAPublicKeySpec;
importjava.security.spec.RSAPrivateKeySpec;
importjava.security.spec.InvalidKeySpecException;
importjava.security.interfaces.RSAPrivateKey;
importjava.security.interfaces.RSAPublicKey;
importjava.io.*;
importjava.math.BigInteger;
/**
*RSA工具类。提供加密,解密,生成密钥对等方法。
*需要到http://www.bouncycastle.org下载bcprov-jdk14-123.jar。
*@authorxiaoyusong
*mail:xiaoyusong@etang.com
*msn:xiao_yu_song@hotmail.com
*@since2004-5-20
*
*/
publicclassRSAUtil{
/**
*生成密钥对
*@returnKeyPair
*@throwsEncryptException
*/
publicstaticKeyPairgenerateKeyPair()throwsEncryptException{
try{
KeyPairGeneratorkeyPairGen=KeyPairGenerator.getInstance("RSA",
neworg.bouncycastle.jce.provider.BouncyCastleProvider());
finalintKEY_SIZE=1024;//没什么好说的了,这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低
keyPairGen.initialize(KEY_SIZE,newSecureRandom());
KeyPairkeyPair=keyPairGen.genKeyPair();
returnkeyPair;
}catch(Exceptione){
thrownewEncryptException(e.getMessage());
}
}
/**
*生成公钥
*@parammodulus
*@parampublicExponent
*@returnRSAPublicKey
*@throwsEncryptException
*/
publicstaticRSAPublicKeygenerateRSAPublicKey(byte[]modulus,byte[]publicExponent)throwsEncryptException{
KeyFactorykeyFac=null;
try{
keyFac=KeyFactory.getInstance("RSA",neworg.bouncycastle.jce.provider.BouncyCastleProvider());
}catch(NoSuchAlgorithmExceptionex){
thrownewEncryptException(ex.getMessage());
}
RSAPublicKeySpecpubKeySpec=newRSAPublicKeySpec(newBigInteger(modulus),newBigInteger(publicExponent));
try{
return(RSAPublicKey)keyFac.generatePublic(pubKeySpec);
}catch(InvalidKeySpecExceptionex){
thrownewEncryptException(ex.getMessage());
}
}
/**
*生成私钥
*@parammodulus
*@paramprivateExponent
*@returnRSAPrivateKey
*@throwsEncryptException
*/
publicstaticRSAPrivateKeygenerateRSAPrivateKey(byte[]modulus,byte[]privateExponent)throwsEncryptException{
KeyFactorykeyFac=null;
try{
keyFac=KeyFactory.getInstance("RSA",neworg.bouncycastle.jce.provider.BouncyCastleProvider());
}catch(NoSuchAlgorithmExceptionex){
thrownewEncryptException(ex.getMessage());
}
RSAPrivateKeySpecpriKeySpec=newRSAPrivateKeySpec(newBigInteger(modulus),newBigInteger(privateExponent));
try{
return(RSAPrivateKey)keyFac.generatePrivate(priKeySpec);
}catch(InvalidKeySpecExceptionex){
thrownewEncryptException(ex.getMessage());
}
}
/**
*加密
*@paramkey加密的密钥
*@paramdata待加密的明文数据
*@return加密后的数据
*@throwsEncryptException
*/
publicstaticbyte[]encrypt(Keykey,byte[]data)throwsEncryptException{
try{
Ciphercipher=Cipher.getInstance("RSA",neworg.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE,key);
intblockSize=cipher.getBlockSize();//获得加密块大小,如:加密前数据为128个byte,而key_size=1024加密块大小为127byte,加密后为128个byte;因此共有2个加密块,第一个127byte第二个为1个byte
intoutputSize=cipher.getOutputSize(data.length);//获得加密块加密后块大小
intleavedSize=data.length%blockSize;
intblocksSize=leavedSize!=0?data.length/blockSize+1:data.length/blockSize;
byte[]raw=newbyte[outputSize*blocksSize];
inti=0;
while(data.length-i*blockSize>0){
if(data.length-i*blockSize>blockSize)
cipher.doFinal(data,i*blockSize,blockSize,raw,i*outputSize);
else
cipher.doFinal(data,i*blockSize,data.length-i*blockSize,raw,i*outputSize);
//这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到ByteArrayOutputStream中,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了OutputSize所以只好用dofinal方法。
i++;
}
returnraw;
}catch(Exceptione){
thrownewEncryptException(e.getMessage());
}
}
/**
*解密
*@paramkey解密的密钥
*@paramraw已经加密的数据
*@return解密后的明文
*@throwsEncryptException
*/
publicstaticbyte[]decrypt(Keykey,byte[]raw)throwsEncryptException{
try{
Ciphercipher=Cipher.getInstance("RSA",neworg.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(cipher.DECRYPT_MODE,key);
intblockSize=cipher.getBlockSize();
ByteArrayOutputStreambout=newByteArrayOutputStream(64);
intj=0;
while(raw.length-j*blockSize>0){
bout.write(cipher.doFinal(raw,j*blockSize,blockSize));
j++;
}
returnbout.toByteArray();
}catch(Exceptione){
thrownewEncryptException(e.getMessage());
}
}
/**
*
*@paramargs
*@throwsException
*/
publicstaticvoidmain(String[]args)throwsException{
Filefile=newFile("test.html");
FileInputStreamin=newFileInputStream(file);
ByteArrayOutputStreambout=newByteArrayOutputStream();
byte[]tmpbuf=newbyte[1024];
intcount=0;
while((count=in.read(tmpbuf))!=-1){
bout.write(tmpbuf,0,count);
tmpbuf=newbyte[1024];
}
in.close();
byte[]orgData=bout.toByteArray();
KeyPairkeyPair=RSAUtil.generateKeyPair();
RSAPublicKeypubKey=(RSAPublicKey)keyPair.getPublic();
RSAPrivateKeypriKey=(RSAPrivateKey)keyPair.getPrivate();
byte[]pubModBytes=pubKey.getModulus().toByteArray();
byte[]pubPubExpBytes=pubKey.getPublicExponent().toByteArray();
byte[]priModBytes=priKey.getModulus().toByteArray();
byte[]priPriExpBytes=priKey.getPrivateExponent().toByteArray();
RSAPublicKeyrecoveryPubKey=RSAUtil.generateRSAPublicKey(pubModBytes,pubPubExpBytes);
RSAPrivateKeyrecoveryPriKey=RSAUtil.generateRSAPrivateKey(priModBytes,priPriExpBytes);
byte[]raw=RSAUtil.encrypt(priKey,orgData);
file=newFile("encrypt_result.dat");
OutputStreamout=newFileOutputStream(file);
out.write(raw);
out.close();
byte[]data=RSAUtil.decrypt(recoveryPubKey,raw);
file=newFile("decrypt_result.html");
out=newFileOutputStream(file);
out.write(data);
out.flush();
out.close();
}
}
加密可以用公钥,解密用私钥;或者加密用私钥。通常非对称加密是非常消耗资源的,因此可以对大数据用对称加密如:des(具体代码可以看我以前发的贴子),而对其对称密钥进行非对称加密,这样既保证了数据的安全,还能保证效率。
本文地址:http://www.45fan.com/bcdm/66940.html