導入javax . crypto . cipher;
導入Java . security . *;
導入Java . security . spec . rspublickeyspec;
導入Java . security . spec . rsaprivatekeyspec;
導入Java . security . spec . invalidkeyspecexception;
導入Java . security . interfaces . rsaprivatekey;
導入Java . security . interfaces . RSA public key;
導入Java . io . *;
導入Java . math . big integer;
/**
* RSA工具類。提供對等的加密、解密和密鑰生成方法。
*您需要從http://www.bouncycastle.org下載BC prov-JDK 14-123 . jar。
* RSA加密原理概述
* RSA的安全性依賴於大數的分解,公鑰和私鑰都是兩個大素數(十進制數大於100)的函數。
*推測從壹個密鑰和密文推斷明文的難度相當於分解兩個大素數的乘積。
* ===================================================================
*(該算法的安全性尚未得到理論證明)
* ===================================================================
*密鑰生成:
* 1.選擇兩個大素數p,q,計算n = p * q;
* 2.隨機選擇加密密鑰E,要求E和(p-1)*(q-1)互為素數。
* 3.用歐幾裏德算法計算解密密鑰D,使其滿足E * D = 1(mod(P-1)*(Q-1))(其中N和D也互質)。
* 4:公鑰是(n,e),私鑰是(n,d)。
* ===================================================================
*加密和解密方法:
* 1.首先,將待加密的信息m(二進制表示)分成等長的數據塊M1,m2,...,MI塊的長度為s(盡可能大),其中2 s
* 2:對應的密文為ci = mi e (mod n)。
* 3:解密時進行如下計算:mi = ci d (mod n)。
* ===================================================================
* RSA速度
*因為大數的計算,RSA最快的情況是比DES慢100倍,無論是軟件實現還是硬件實現。
*速度壹直是RSA的短板。壹般來說,它只用於加密少量數據。
*文件名:rsautil.java
* @作者趙峰
*版本:1.0.1
*說明:此算法是從網絡中提取的,是RSA算法的實現
*創建時間:2009年7月-10 09:58:16
*文件描述:首先生成兩個大素數,然後解密密鑰< br & gt
*/
公共類RSAUtil {
//密鑰對
private KeyPair keyPair = null
/**
*初始化密鑰對
*/
public RSAUtil(){
嘗試{
this . key pair = this . generatekeypair();
} catch(異常e) {
e . printstacktrace();
}
}
/**
*生成密鑰對
* @return密鑰對
* @拋出異常
*/
私有密鑰對generateKeyPair()引發異常{
嘗試{
KeyPairGenerator keyPairGen = KeyPairGenerator . getinstance(" RSA ",new org . bouncy castle . JCE . provider . bouncy castle provider());
//這個值與塊加密的大小有關,可以改變,但不能太大,否則效率低。
final int KEY _ SIZE = 1024;
keyPairGen.initialize(KEY_SIZE,new SecureRandom());
key pair key pair = key pairgen . genkey pair();
返回密鑰對;
} catch(異常e) {
拋出新的異常(e . getmessage());
}
}
/**
*生成公鑰
* @參數模數
* @ param public index
* @return RSAPublicKey
* @拋出異常
*/
私有RSA public key generatorsapublickey(byte[]module,byte[] publicExponent)引發異常{
KeyFactory keyFac = null
嘗試{
key fac = key factory . getinstance(" RSA ",new org . bouncy castle . JCE . provider . bouncy castle provider());
} catch(nosuchalgorithm exception ex){
拋出新異常(ex . getmessage());
}
rspublickeyspec pubKeySpec = new rspublickeyspec(new big integer(模數),new big integer(public exponent));
嘗試{
return(RSA public key)key fac . generate public(pubkey spec);
} catch(InvalidKeySpecException ex){
拋出新異常(ex . getmessage());
}
}
/**
*生成私鑰
* @參數模數
* @ param privateExponent
* @return RSAPrivateKey
* @拋出異常
*/
私有RSAPrivateKey生成器RSAPrivateKey,byte[] privateExponent)引發異常{
KeyFactory keyFac = null
嘗試{
key fac = key factory . getinstance(" RSA ",new org . bouncy castle . JCE . provider . bouncy castle provider());
} catch(nosuchalgorithm exception ex){
拋出新異常(ex . getmessage());
}
RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new big integer(模數),new big integer(private exponent));
嘗試{
return(RSAPrivateKey)key fac . generate private(priKeySpec);
} catch(InvalidKeySpecException ex){
拋出新異常(ex . getmessage());
}
}
/**
*加密
* @param key加密密鑰
* @param data要加密的明文數據
* @返回加密數據
* @拋出異常
*/
公共字節[]加密(密鑰Key,字節[]數據)引發異常{
嘗試{
cipher cipher = cipher . getinstance(" RSA ",new org . bouncy castle . JCE . provider . bouncy castle provider());
cipher.init(密碼。ENCRYPT_MODE,key);
//獲取加密塊大小,比如加密前的數據是128字節,而key_size=1024的加密塊大小是127字節,加密塊大小是128字節;
//所以* * *有兩個加密塊,第壹個是127字節,第二個是1字節。
int block size = cipher . get block size();
//system . out . println(" block size:"+block size);
int output size = cipher . getoutputsize(data . length);//獲取加密塊的加密塊大小
// System.out.println("加密塊大小:"+output size);
int leavedSize = data . length % block size;
//system . out . println(" leavedSize:"+leavedSize);
int blocksSize = leavedSize!= 0 ?data . length/block size+1:data . length/block size;
byte[]raw = new byte[output size * blocks size];
int I = 0;
while(data . length-I * block size & gt;0) {
if(data . length-I * block size & gt;塊大小)
cipher.doFinal(data,i * blockSize,blockSize,raw,I * output size);
其他
cipher.doFinal(data,i * blockSize,data.length - i * blockSize,raw,I * output size);
doUpdate方法不可用。我查了壹下源代碼,發現每次doUpdate之後除了把byte[]放到ByteArrayOutputStream之外,並沒有什麽實際的動作。
//而所有的byte[] []只會在doFinal結束時加密,但此時加密的塊大小可能已經超過了OutputSize,所以我們不得不使用dofinal方法。
i++;
}
返回raw
} catch(異常e) {
拋出新的異常(e . getmessage());
}
}
/**
*解密
* @param key解密密鑰
* @param原始加密數據
* @返回解密的明文
* @拋出異常
*/
@SuppressWarnings("靜態訪問")
公共字節[]解密(密鑰Key,字節[] raw)引發異常{
嘗試{
cipher cipher = cipher . getinstance(" RSA ",new org . bouncy castle . JCE . provider . bouncy castle provider());
cipher.init(密碼。DECRYPT_MODE,key);
int block size = cipher . get block size();
ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
int j = 0;
while(raw . length-j * block size & gt;0) {
bout.write(cipher.doFinal(raw,j * blockSize,block size));
j++;
}
返回bout . tobytearray();
} catch(異常e) {
拋出新的異常(e . getmessage());
}
}
/**
*返回公鑰
* @返回
* @拋出異常
*/
公共RSAPublicKey getRSAPublicKey()引發異常{
//獲取公鑰
RSA public key pubKey =(RSA public key)key pair . get public();
//獲取公鑰系數(以字節數組的形式)
byte[]pubModBytes = pubkey . get module()。toByteArray();
//返回公鑰的公共索引(以字節數組的形式)
byte[]pubexpbytes = pubkey . getpublic exponent()。toByteArray();
//生成公鑰
RSA public key recovery pubkey = this . generatersapublickey(pubModBytes,pubexpbytes);
返回recoveryPubKey
}
/**
*獲取私鑰
* @返回
* @拋出異常
*/
public RSAPrivateKey getRSAPrivateKey()引發異常{
//獲取私鑰
RSAPrivateKey priKey =(RSAPrivateKey)key pair . get private();
//返回私鑰系數(字節數組)
byte[]priModBytes = prikey . get module()。toByteArray();
//返回私鑰私有索引(以字節數組的形式)
byte[]priPriExpBytes = prikey . getprivate exponent()。toByteArray();
//生成私鑰
RSAPrivateKey recoveryPriKey = this . generatersaprivatekey(priModBytes,pripripriexpbytes);
return recoveryPriKey
}
/**
*測試
* @param args
* @拋出異常
*/
公共靜態void main(String[] args)引發異常{
RSA util RSA = new RSA util();
String str = "八龍神雕俠侶傳白馬嘯西風";
RSA public key pubKey = RSA . getrsa public key();
RSAPrivateKey priKey = RSA . getrsaprivatekey();
//system . out . println(" encrypted = = "+newstring(RSA . encrypt(pubkey,str . getbytes())));
String MW = new String(RSA . encrypt(pubKey,str . getbytes()));
System.out.println("加密後:"+MW);
// System.out.println("解密後:");
system . out . println(" after decryption = = "+new string(RSA。解密(prikey,RSA。加密(公鑰,字符串。getbytes()))));
}
}