實現javarsa
代碼如下:main方法用於測試的,不是演算法本身。
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import javax.crypto.Cipher;
public class RSACrypto
{
private final static String RSA = "RSA";
public static PublicKey uk;
public static PrivateKey rk;
public static void generateKey() throws Exception
{
KeyPairGenerator gen = KeyPairGenerator.getInstance(RSA);
gen.initialize(512, new SecureRandom());
KeyPair keyPair = gen.generateKeyPair();
uk = keyPair.getPublic();
rk = keyPair.getPrivate();
}
private static byte[] encrypt(String text, PublicKey pubRSA) throws Exception
{
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.ENCRYPT_MODE, pubRSA);
return cipher.doFinal(text.getBytes());
}
public final static String encrypt(String text)
{
try {
return byte2hex(encrypt(text, uk));
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
public final static String decrypt(String data)
{
try{
return new String(decrypt(hex2byte(data.getBytes())));
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
private static byte[] decrypt(byte[] src) throws Exception
{
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.DECRYPT_MODE, rk);
return cipher.doFinal(src);
}
public static String byte2hex(byte[] b)
{
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n ++)
{
stmp = Integer.toHexString(b[n] & 0xFF);
if (stmp.length() == 1)
hs += ("0" + stmp);
else
hs += stmp;
}
return hs.toUpperCase();
}
public static byte[] hex2byte(byte[] b)
{
if ((b.length % 2) != 0)
throw new IllegalArgumentException("長度不是偶數");
byte[] b2 = new byte[b.length / 2];
for (int n = 0; n < b.length; n += 2)
{
String item = new String(b, n, 2);
b2[n/2] = (byte)Integer.parseInt(item, 16);
}
return b2;
}
//just for test
public static void main(String args[])
{
try
{
RSACrypto.generateKey();
String cipherText = RSACrypto.encrypt("asdfghjh");
System.out.println(cipherText);
String plainText = RSACrypto.decrypt(cipherText);
System.out.println(plainText);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
求採納為滿意回答。
② 用JAVA實現RSA演算法的加密解密 跪求
#####################################
我已經說的很清楚了。。。只要把我說的用程序寫下來,加個菜單就行了。。。要是這樣都不會的話。。。那就當我沒說了。。。
####################################
RSA。。。難道你自己建立PKI,否則沒法弄。。。
你說這個題。。直接手算的了。。。又不是大數
N = P * Q = 1739
N的歐拉函數
F(N) = ( p - 1 ) * ( Q - 1 ) = 1656
然後算模擬嘛。。。5 模 1656的逆。。。
1656 = 1 + 1655 = 1 + 5 * 331
所以5模1656的逆就是-331 = 1656 - 331 = 1325
所以D = 1325啦
你要加密你至少告訴我明文是什麼吧。。。。
如果加密明文M的話,密文C = M 模 1739的E次冪
解密是M = C 模1739的D次冪
小數直接手算啦~費馬小定理,從左向右計算,可以簡化一部分計算,不過你這個題已經差不多最簡化了。。。。你這個題實際上就是用來手算的。真正RSA一般人根本做不出來,光是素性檢驗就很麻煩了。。而且就算你能實現,你有PKI嗎???沒有PKI。。。RSA的安全從何而來???
我們也上學期剛學的密碼。。。呵呵~~~有問題繼續問。。。現在無聊啊。。
③ java RSA實現對文件加密解密
這個我不清楚。
對文件加密,我使用的是超級加密3000.
超級加密3000採用國際上成熟的加密演算法和安全快速的加密方法,可以有效保障數據安全!
具體操作方法:
1下載安裝超級加密3000。
2 然後在需要加密的文件上單擊滑鼠右鍵選擇加密。
3 在彈出的文件加密窗口中設置文件加密密碼就OK了。
超級加密3000的下載地址你可以在網路上搜索超級加密3000,第一個就是。
④ 如何實現用javascript實現rsa加解密
服務端生成公鑰與私鑰,保存。
客戶端在請求到登錄頁面後,隨機生成一字元串。
後此隨機字元串作為密鑰加密密碼,再用從服務端獲取到的公鑰加密生成的隨機字元串
將此兩段密文傳入服務端,服務端用私鑰解出隨機字元串,再用此私鑰解出加密的密文。這其中有一個關鍵是解決服務端的公鑰,傳入客戶端,客戶端用此公鑰加密字元串後,後又能在服務端用私鑰解出。
步驟:
服務端的RSAJava實現:
/**
*
*/
packagecom.sunsoft.struts.util;
importjava.io.ByteArrayOutputStream;
importjava.io.FileInputStream;
importjava.io.FileOutputStream;
importjava.io.ObjectInputStream;
importjava.io.ObjectOutputStream;
importjava.math.BigInteger;
importjava.security.KeyFactory;
importjava.security.KeyPair;
importjava.security.KeyPairGenerator;
importjava.security.NoSuchAlgorithmException;
importjava.security.PrivateKey;
importjava.security.PublicKey;
importjava.security.SecureRandom;
importjava.security.interfaces.RSAPrivateKey;
importjava.security.interfaces.RSAPublicKey;
importjava.security.spec.InvalidKeySpecException;
importjava.security.spec.RSAPrivateKeySpec;
importjava.security.spec.RSAPublicKeySpec;
importjavax.crypto.Cipher;/**
*RSA工具類。提供加密,解密,生成密鑰對等方法。
*需要到
下載bcprov-jdk14-123.jar。
*
*/
publicclassRSAUtil{
/**
**生成密鑰對*
*
*@returnKeyPair*
*@throwsEncryptException
*/
()throwsException{
try{
KeyPairGeneratorkeyPairGen=KeyPairGenerator.getInstance("RSA",
neworg.bouncycastle.jce.provider.BouncyCastleProvider());
finalintKEY_SIZE=1024;//沒什麼好說的了,這個值關繫到塊加密的大小,可以更改,但是不要太大,否則效率會低
keyPairGen.initialize(KEY_SIZE,newSecureRandom());
KeyPairkeyPair=keyPairGen.generateKeyPair();
saveKeyPair(keyPair);
returnkeyPair;
}catch(Exceptione){
thrownewException(e.getMessage());
}
}
publicstaticKeyPairgetKeyPair()throwsException{
FileInputStreamfis=newFileInputStream("C:/RSAKey.txt");
ObjectInputStreamoos=newObjectInputStream(fis);
KeyPairkp=(KeyPair)oos.readObject();
oos.close();
fis.close();
returnkp;
}
publicstaticvoidsaveKeyPair(KeyPairkp)throwsException{
FileOutputStreamfos=newFileOutputStream("C:/RSAKey.txt");
ObjectOutputStreamoos=newObjectOutputStream(fos);
//生成密鑰
oos.writeObject(kp);
oos.close();
fos.close();
}
/**
**生成公鑰*
*
*@parammolus*
*@parampublicExponent*
*@returnRSAPublicKey*
*@throwsException
*/
(byte[]molus,
byte[]publicExponent)throwsException{
KeyFactorykeyFac=null;
try{
keyFac=KeyFactory.getInstance("RSA",
neworg.bouncycastle.jce.provider.BouncyCastleProvider());
}catch(NoSuchAlgorithmExceptionex){
thrownewException(ex.getMessage());
}
RSAPublicKeySpecpubKeySpec=newRSAPublicKeySpec(newBigInteger(
molus),newBigInteger(publicExponent));
try{
return(RSAPublicKey)keyFac.generatePublic(pubKeySpec);
}catch(InvalidKeySpecExceptionex){
thrownewException(ex.getMessage());
}
}
/**
**生成私鑰*
*
*@parammolus*
*@paramprivateExponent*
*@returnRSAPrivateKey*
*@throwsException
*/
(byte[]molus,
byte[]privateExponent)throwsException{
KeyFactorykeyFac=null;
try{
keyFac=KeyFactory.getInstance("RSA",
neworg.bouncycastle.jce.provider.BouncyCastleProvider());
}catch(NoSuchAlgorithmExceptionex){
thrownewException(ex.getMessage());
}
RSAPrivateKeySpecpriKeySpec=newRSAPrivateKeySpec(newBigInteger(
molus),newBigInteger(privateExponent));
try{
return(RSAPrivateKey)keyFac.generatePrivate(priKeySpec);
}catch(InvalidKeySpecExceptionex){
thrownewException(ex.getMessage());
}
}
/**
**加密*
*
*@paramkey
*加密的密鑰*
*@paramdata
*待加密的明文數據*
*@return加密後的數據*
*@throwsException
*/
publicstaticbyte[]encrypt(PublicKeypk,byte[]data)throwsException{
try{
Ciphercipher=Cipher.getInstance("RSA",
neworg.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE,pk);
intblockSize=cipher.getBlockSize();//獲得加密塊大小,如:加密前數據為128個byte,而key_size=1024
//加密塊大小為127
//byte,加密後為128個byte;因此共有2個加密塊,第一個127
//byte第二個為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){
thrownewException(e.getMessage());
}
}
/**
**解密*
*
*@paramkey
*解密的密鑰*
*@paramraw
*已經加密的數據*
*@return解密後的明文*
*@throwsException
*/
publicstaticbyte[]decrypt(PrivateKeypk,byte[]raw)throwsException{
try{
Ciphercipher=Cipher.getInstance("RSA",
neworg.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(cipher.DECRYPT_MODE,pk);
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){
thrownewException(e.getMessage());
}
}
/**
***
*
*@paramargs*
*@throwsException
*/
publicstaticvoidmain(String[]args)throwsException{
RSAPublicKeyrsap=(RSAPublicKey)RSAUtil.generateKeyPair().getPublic();
Stringtest="helloworld";
byte[]en_test=encrypt(getKeyPair().getPublic(),test.getBytes());
byte[]de_test=decrypt(getKeyPair().getPrivate(),en_test);
System.out.println(newString(de_test));
}
}測試頁面IndexAction.java:
/*
*GeneratedbyMyEclipseStruts
*Templatepath:templates/java/JavaClass.vtl
*/
packagecom.sunsoft.struts.action;
importjava.security.interfaces.RSAPrivateKey;
importjava.security.interfaces.RSAPublicKey;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.apache.struts.action.Action;
importorg.apache.struts.action.ActionForm;
importorg.apache.struts.action.ActionForward;
importorg.apache.struts.action.ActionMapping;
importcom.sunsoft.struts.util.RSAUtil;
/**
*MyEclipseStruts
*Creationdate:06-28-2008
*
*XDocletdefinition:
*@struts.actionvalidate="true"
*/
{
/*
*GeneratedMethods
*/
/**
*Methodexecute
*@parammapping
*@paramform
*@paramrequest
*@paramresponse
*@returnActionForward
*/
publicActionForwardexecute(ActionMappingmapping,ActionFormform,
HttpServletRequestrequest,HttpServletResponseresponse)throwsException{
RSAPublicKeyrsap=(RSAPublicKey)RSAUtil.getKeyPair().getPublic();
Stringmole=rsap.getMolus().toString(16);
Stringempoent=rsap.getPublicExponent().toString(16);
System.out.println("mole");
System.out.println(mole);
System.out.println("empoent");
System.out.println(empoent);
request.setAttribute("m",mole);
request.setAttribute("e",empoent);
returnmapping.findForward("login");
}
}通過此action進入登錄頁面,並傳入公鑰的Molus 與PublicExponent的hex編碼形式。
⑤ 有一段用java實現rsa加解密的程序看不懂,希望高手幫我做下注釋,詳細些,謝謝
//引入文件
import java.security.*;
import javax.crypto.*;
/**
* RSACryptography
* RSACryptography use the privated key to encrypt the plain text and decrypt
* the cipher text with the public key
*/
public class RSACryptography {
Cipher cipher;
/**
構造函數,就是你每次new這個對象RSACryptography 時候就會執行裡面的方法
返回一個Cipher對象(其實他就是用來加密解密的)
*/
public RSACryptography() {
try {
cipher = Cipher.getInstance("RSA");//返回一個cipher對象,該類
//應該是單例的
} catch (NoSuchAlgorithmException e) {//拋出異常,沒什麼說的
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
}
/**
好了,重點來了,你需要加密解密的就調用這個方法encrypt_decrypt(),傳入一個byte[]的類型值byteInput,,就是你要加密的東西,在傳入一個key,這個key 就像鑰匙一樣,你根據這個key進行加密,也可以根據這個key進行解密的,boolean 類型的 crypto,如果true就是加密,false就是解密
*/
public byte[] encrypt_decrypt(byte[] byteInput, Key key, boolean crypto) {
try {
if(crypto){
cipher.init(Cipher.ENCRYPT_MODE,key);//加密前初始化
}else{
cipher.init(Cipher.DECRYPT_MODE,key);//解密前初始化
}
byte[] cipherByte = cipher.doFinal(byteInput);//進行加密或解密
return cipherByte;//返回你的加密或者解密值類型為byte[]
} catch (InvalidKeyException e) {//拋出異常
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
}
⑥ 如何用java實現128位密鑰的RSA演算法
importjavax.crypto.Cipher;
importsun.misc.BASE64Decoder;
importsun.misc.BASE64Encoder;
importjava.io.FileInputStream;
importjava.io.FileOutputStream;
importjava.io.ObjectInputStream;
importjava.io.ObjectOutputStream;
importjava.security.Key;
importjava.security.KeyPair;
importjava.security.KeyPairGenerator;
importjava.security.SecureRandom;
publicclassRSA_Encrypt{
/**指定加密演算法為DESede*/
privatestaticStringALGORITHM="RSA";
/**指定key的大小*/
privatestaticintKEYSIZE=128;
/**指定公鑰存放文件*/
privatestaticStringPUBLIC_KEY_FILE="PublicKey";
/**指定私鑰存放文件*/
privatestaticStringPRIVATE_KEY_FILE="PrivateKey";
//privatestaticStringPUBLIC_KEY_FILE="D://PublicKey.a";
//privatestaticStringPRIVATE_KEY_FILE="D://PrivateKey.a";
/**
*生成密鑰對
*/
()throwsException{
/**RSA演算法要求有一個可信任的隨機數源*/
SecureRandomsr=newSecureRandom();
/**為RSA演算法創建一個KeyPairGenerator對象*/
KeyPairGeneratorkpg=KeyPairGenerator.getInstance(ALGORITHM);
/**利用上面的隨機數據源初始化這個KeyPairGenerator對象*/
kpg.initialize(KEYSIZE,sr);
/**生成密匙對*/
KeyPairkp=kpg.generateKeyPair();
/**得到公鑰*/
KeypublicKey=kp.getPublic();
/**得到私鑰*/
KeyprivateKey=kp.getPrivate();
/**用對象流將生成的密鑰寫入文件*/
ObjectOutputStreamoos1=newObjectOutputStream(newFileOutputStream(PUBLIC_KEY_FILE));
ObjectOutputStreamoos2=newObjectOutputStream(newFileOutputStream(PRIVATE_KEY_FILE));
oos1.writeObject(publicKey);
oos2.writeObject(privateKey);
/**清空緩存,關閉文件輸出流*/
oos1.close();
oos2.close();
}
/**
*加密方法
*source:源數據
*/
publicstaticStringencrypt(Stringsource)throwsException{
generateKeyPair();
/**將文件中的公鑰對象讀出*/
ObjectInputStreamois=newObjectInputStream(newFileInputStream(PUBLIC_KEY_FILE));
Keykey=(Key)ois.readObject();
ois.close();
/**得到Cipher對象來實現對源數據的RSA加密*/
Ciphercipher=Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE,key);
byte[]b=source.getBytes();
/**執行加密操作*/
byte[]b1=cipher.doFinal(b);
BASE64Encoderencoder=newBASE64Encoder();
returnencoder.encode(b1);
}
/**
*解密演算法
*cryptograph:密文
*/
publicstaticStringdecrypt(Stringcryptograph)throwsException{
/**將文件中的私鑰對象讀出*/
ObjectInputStreamois=newObjectInputStream(newFileInputStream(PRIVATE_KEY_FILE));
Keykey=(Key)ois.readObject();
/**得到Cipher對象對已用公鑰加密的數據進行RSA解密*/
Ciphercipher=Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE,key);
BASE64Decoderdecoder=newBASE64Decoder();
byte[]b1=decoder.decodeBuffer(cryptograph);
/**執行解密操作*/
byte[]b=cipher.doFinal(b1);
returnnewString(b);
}
publicstaticvoidmain(String[]args){
try{
Stringsource="HelloWorld!";//要加密的字元串
Stringcryptograph=encrypt(source);
System.out.println(cryptograph);
Stringtarget=decrypt(cryptograph);//解密密文
System.out.println(target);
}catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}//生成的密文
}
}
⑦ java中的rsa\des演算法的方法
rsa加密解密演算法
1978年就出現了這種演算法,它是第一個既能用於數據加密
也能用於數字簽名的演算法。它易於理解和操作,也很流行。算
法的名字以發明者的名字命名:Ron Rivest, AdiShamir 和
Leonard Adleman。但RSA的安全性一直未能得到理論上的證明。
RSA的安全性依賴於大數分解。公鑰和私鑰都是兩個大素數
( 大於 100個十進制位)的函數。據猜測,從一個密鑰和密文
推斷出明文的難度等同於分解兩個大素數的積。
密鑰對的產生:選擇兩個大素數,p 和q 。計算:
n = p * q
然後隨機選擇加密密鑰e,要求 e 和 ( p - 1 ) * ( q - 1 )
互質。最後,利用Euclid 演算法計算解密密鑰d, 滿足
e * d = 1 ( mod ( p - 1 ) * ( q - 1 ) )
其中n和d也要互質。數e和
n是公鑰,d是私鑰。兩個素數p和q不再需要,應該丟棄,不要讓任
何人知道。 加密信息 m(二進製表示)時,首先把m分成等長數據
塊 m1 ,m2,..., mi ,塊長s,其中 2^s <= n, s 盡可能的大。對
應的密文是:
ci = mi^e ( mod n ) ( a )
解密時作如下計算:
mi = ci^d ( mod n ) ( b )
RSA 可用於數字簽名,方案是用 ( a ) 式簽名, ( b )
式驗證。具體操作時考慮到安全性和 m信息量較大等因素,一般是先
作 HASH 運算。
RSA 的安全性。
RSA的安全性依賴於大數分解,但是否等同於大數分解一直未能得到理
論上的證明,因為沒有證明破解RSA就一定需要作大數分解。假設存在
一種無須分解大數的演算法,那它肯定可以修改成為大數分解演算法。目前,
RSA的一些變種演算法已被證明等價於大數分解。不管怎樣,分解n是最顯
然的攻擊方法。現在,人們已能分解140多個十進制位的大素數。因此,
模數n必須選大一些,因具體適用情況而定。
RSA的速度:
由於進行的都是大數計算,使得RSA最快的情況也比DES慢上100倍,無論
是軟體還是硬體實現。速度一直是RSA的缺陷。一般來說只用於少量數據
加密。
RSA的選擇密文攻擊:
RSA在選擇密文攻擊面前很脆弱。一般攻擊者是將某一信息作一下偽裝
(Blind),讓擁有私鑰的實體簽署。然後,經過計算就可得到它所想要的信
息。實際上,攻擊利用的都是同一個弱點,即存在這樣一個事實:乘冪保
留了輸入的乘法結構:
( XM )^d = X^d *M^d mod n
前面已經提到,這個固有的問題來自於公鑰密碼系統的最有用的特徵
--每個人都能使用公鑰。但從演算法上無法解決這一問題,主要措施有
兩條:一條是採用好的公鑰協議,保證工作過程中實體不對其他實體
任意產生的信息解密,不對自己一無所知的信息簽名;另一條是決不
對陌生人送來的隨機文檔簽名,簽名時首先使用One-Way HashFunction
對文檔作HASH處理,或同時使用不同的簽名演算法。在中提到了幾種不
同類型的攻擊方法。
RSA的公共模數攻擊。
若系統中共有一個模數,只是不同的人擁有不同的e和d,系統將是危險
的。最普遍的情況是同一信息用不同的公鑰加密,這些公鑰共模而且互
質,那末該信息無需私鑰就可得到恢復。設P為信息明文,兩個加密密鑰
為e1和e2,公共模數是n,則:
C1 = P^e1 mod n
C2 = P^e2 mod n
密碼分析者知道n、e1、e2、C1和C2,就能得到P。
因為e1和e2互質,故用Euclidean演算法能找到r和s,滿足:
r * e1 + s * e2 = 1
假設r為負數,需再用Euclidean演算法計算C1^(-1),則
( C1^(-1) )^(-r) * C2^s = P mod n
另外,還有其它幾種利用公共模數攻擊的方法。總之,如果知道給定模數
的一對e和d,一是有利於攻擊者分解模數,一是有利於攻擊者計算出其它
成對的e』和d』,而無需分解模數。解決辦法只有一個,那就是不要共享
模數n。
RSA的小指數攻擊。 有一種提高
RSA速度的建議是使公鑰e取較小的值,這樣會使加密變得易於實現,速度
有所提高。但這樣作是不安全的,對付辦法就是e和d都取較大的值。
RSA演算法是第一個能同時用於加密和數字簽名的演算法,也易於理解和操作。
RSA是被研究得最廣泛的公鑰演算法,從提出到現在已近二十年,經歷了各
種攻擊的考驗,逐漸為人們接受,普遍認為是目前最優秀的公鑰方案之一。
RSA的安全性依賴於大數的因子分解,但並沒有從理論上證明破譯RSA的難
度與大數分解難度等價。即RSA的重大缺陷是無法從理論上把握它的保密性
能如何,而且密碼學界多數人士傾向於因子分解不是NPC問題。
RSA的缺點主要有:
A)產生密鑰很麻煩,受到素數產生技術的限制,因而難以做到一次
一密。B)分組長度太大,為保證安全性,n 至少也要 600 bits
以上,使運算代價很高,尤其是速度較慢,較對稱密碼演算法慢幾個數量級;
且隨著大數分解技術的發展,這個長度還在增加,不利於數據格式的標准化。
目前,SET(Secure Electronic Transaction)協議中要求CA採用2048比特長
的密鑰,其他實體使用1024比特的密鑰。
參考資料:http://superpch.josun.com.cn/bbs/PrintPost.asp?ThreadID=465
CRC加解密演算法
http://www.bouncycastle.org/
⑧ 求RSA演算法JAVA實現源代碼(帶界面的)
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.io.*;
import java.math.BigInteger;
/**
* RSA 工具類。提供加密,解密,生成密鑰對等方法。
* 需要到http://www.bouncycastle.org下載bcprov-jdk14-123.jar。
* @author xiaoyusong
* mail: [email protected]
* msn:[email protected]
* @since 2004-5-20
*
*/
public class RSAUtil {
/**
* 生成密鑰對
* @return KeyPair
* @throws EncryptException
*/
public static KeyPair generateKeyPair() throws EncryptException {
try {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",
new org.bouncycastle.jce.provider.BouncyCastleProvider());
final int KEY_SIZE = 1024;//沒什麼好說的了,這個值關繫到塊加密的大小,可以更改,但是不要太大,否則效率會低
keyPairGen.initialize(KEY_SIZE, new SecureRandom());
KeyPair keyPair = keyPairGen.genKeyPair();
return keyPair;
} catch (Exception e) {
throw new EncryptException(e.getMessage());
}
}
/**
* 生成公鑰
* @param molus
* @param publicExponent
* @return RSAPublicKey
* @throws EncryptException
*/
public static RSAPublicKey generateRSAPublicKey(byte[] molus, byte[] publicExponent) throws EncryptException {
KeyFactory keyFac = null;
try {
keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
} catch (NoSuchAlgorithmException ex) {
throw new EncryptException(ex.getMessage());
}
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(molus), new BigInteger(publicExponent));
try {
return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);
} catch (InvalidKeySpecException ex) {
throw new EncryptException(ex.getMessage());
}
}
/**
* 生成私鑰
* @param molus
* @param privateExponent
* @return RSAPrivateKey
* @throws EncryptException
*/
public static RSAPrivateKey generateRSAPrivateKey(byte[] molus, byte[] privateExponent) throws EncryptException {
KeyFactory keyFac = null;
try {
keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
} catch (NoSuchAlgorithmException ex) {
throw new EncryptException(ex.getMessage());
}
RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(molus), new BigInteger(privateExponent));
try {
return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);
} catch (InvalidKeySpecException ex) {
throw new EncryptException(ex.getMessage());
}
}
/**
* 加密
* @param key 加密的密鑰
* @param data 待加密的明文數據
* @return 加密後的數據
* @throws EncryptException
*/
public static byte[] encrypt(Key key, byte[] data) throws EncryptException {
try {
Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, key);
int blockSize = cipher.getBlockSize();//獲得加密塊大小,如:加密前數據為128個byte,而key_size=1024 加密塊大小為127 byte,加密後為128個byte;因此共有2個加密塊,第一個127 byte第二個為1個byte
int outputSize = cipher.getOutputSize(data.length);//獲得加密塊加密後塊大小
int leavedSize = data.length % blockSize;
int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;
byte[] raw = new byte[outputSize * blocksSize];
int i = 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++;
}
return raw;
} catch (Exception e) {
throw new EncryptException(e.getMessage());
}
}
/**
* 解密
* @param key 解密的密鑰
* @param raw 已經加密的數據
* @return 解密後的明文
* @throws EncryptException
*/
public static byte[] decrypt(Key key, byte[] raw) throws EncryptException {
try {
Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(cipher.DECRYPT_MODE, key);
int blockSize = cipher.getBlockSize();
ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
int j = 0;
while (raw.length - j * blockSize > 0) {
bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
j++;
}
return bout.toByteArray();
} catch (Exception e) {
throw new EncryptException(e.getMessage());
}
}
/**
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
File file = new File("test.html");
FileInputStream in = new FileInputStream(file);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte[] tmpbuf = new byte[1024];
int count = 0;
while ((count = in.read(tmpbuf)) != -1) {
bout.write(tmpbuf, 0, count);
tmpbuf = new byte[1024];
}
in.close();
byte[] orgData = bout.toByteArray();
KeyPair keyPair = RSAUtil.generateKeyPair();
RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey priKey = (RSAPrivateKey) keyPair.getPrivate();
byte[] pubModBytes = pubKey.getMolus().toByteArray();
byte[] pubPubExpBytes = pubKey.getPublicExponent().toByteArray();
byte[] priModBytes = priKey.getMolus().toByteArray();
byte[] priPriExpBytes = priKey.getPrivateExponent().toByteArray();
RSAPublicKey recoveryPubKey = RSAUtil.generateRSAPublicKey(pubModBytes,pubPubExpBytes);
RSAPrivateKey recoveryPriKey = RSAUtil.generateRSAPrivateKey(priModBytes,priPriExpBytes);
byte[] raw = RSAUtil.encrypt(priKey, orgData);
file = new File("encrypt_result.dat");
OutputStream out = new FileOutputStream(file);
out.write(raw);
out.close();
byte[] data = RSAUtil.decrypt(recoveryPubKey, raw);
file = new File("decrypt_result.html");
out = new FileOutputStream(file);
out.write(data);
out.flush();
out.close();
}
}
http://book.77169.org/data/web5409/20050328/20050328__3830259.html
這個行吧
http://soft.zdnet.com.cn/software_zone/2007/0925/523319.shtml
再參考這個吧
http://topic.csdn.net/t/20040427/20/3014655.html
⑨ RSA PKCS#1在java中怎麼實現
樓主看看下面的代碼是不是你所需要的,這是我原來用的時候收集的
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.io.*;
import java.math.BigInteger;
/**
* RSA 工具類。提供加密,解密,生成密鑰對等方法。
* 需要到http://www.bouncycastle.org下載bcprov-jdk14-123.jar。
* RSA加密原理概述
* RSA的安全性依賴於大數的分解,公鑰和私鑰都是兩個大素數(大於100的十進制位)的函數。
* 據猜測,從一個密鑰和密文推斷出明文的難度等同於分解兩個大素數的積
* ===================================================================
* (該演算法的安全性未得到理論的證明)
* ===================================================================
* 密鑰的產生:
* 1.選擇兩個大素數 p,q ,計算 n=p*q;
* 2.隨機選擇加密密鑰 e ,要求 e 和 (p-1)*(q-1)互質
* 3.利用 Euclid 演算法計算解密密鑰 d , 使其滿足 e*d = 1(mod(p-1)*(q-1)) (其中 n,d 也要互質)
* 4:至此得出公鑰為 (n,e) 私鑰為 (n,d)
* ===================================================================
* 加解密方法:
* 1.首先將要加密的信息 m(二進製表示) 分成等長的數據塊 m1,m2,...,mi 塊長 s(盡可能大) ,其中 2^s<n
* 2:對應的密文是: ci = mi^e(mod n)
* 3:解密時作如下計算: mi = ci^d(mod n)
* ===================================================================
* RSA速度
* 由於進行的都是大數計算,使得RSA最快的情況也比DES慢上100倍,無論是軟體還是硬體實現。
* 速度一直是RSA的缺陷。一般來說只用於少量數據加密。
* 文件名:RSAUtil.java<br>
* @author 趙峰<br>
* 版本:1.0.1<br>
* 描述:本演算法摘自網路,是對RSA演算法的實現<br>
* 創建時間:2009-7-10 下午09:58:16<br>
* 文件描述:首先生成兩個大素數,然後根據Euclid演算法生成解密密鑰<br>
*/
public class RSAUtil {
//密鑰對
private KeyPair keyPair = null;
/**
* 初始化密鑰對
*/
public RSAUtil(){
try {
this.keyPair = this.generateKeyPair();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 生成密鑰對
* @return KeyPair
* @throws Exception
*/
private KeyPair generateKeyPair() throws Exception {
try {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",new org.bouncycastle.jce.provider.BouncyCastleProvider());
//這個值關繫到塊加密的大小,可以更改,但是不要太大,否則效率會低
final int KEY_SIZE = 1024;
keyPairGen.initialize(KEY_SIZE, new SecureRandom());
KeyPair keyPair = keyPairGen.genKeyPair();
return keyPair;
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
/**
* 生成公鑰
* @param molus
* @param publicExponent
* @return RSAPublicKey
* @throws Exception
*/
private RSAPublicKey generateRSAPublicKey(byte[] molus, byte[] publicExponent) throws Exception {
KeyFactory keyFac = null;
try {
keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
} catch (NoSuchAlgorithmException ex) {
throw new Exception(ex.getMessage());
}
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(molus), new BigInteger(publicExponent));
try {
return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);
} catch (InvalidKeySpecException ex) {
throw new Exception(ex.getMessage());
}
}
/**
* 生成私鑰
* @param molus
* @param privateExponent
* @return RSAPrivateKey
* @throws Exception
*/
private RSAPrivateKey generateRSAPrivateKey(byte[] molus, byte[] privateExponent) throws Exception {
KeyFactory keyFac = null;
try {
keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
} catch (NoSuchAlgorithmException ex) {
throw new Exception(ex.getMessage());
}
RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(molus), new BigInteger(privateExponent));
try {
return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);
} catch (InvalidKeySpecException ex) {
throw new Exception(ex.getMessage());
}
}
/**
* 加密
* @param key 加密的密鑰
* @param data 待加密的明文數據
* @return 加密後的數據
* @throws Exception
*/
public byte[] encrypt(Key key, byte[] data) throws Exception {
try {
Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, key);
// 獲得加密塊大小,如:加密前數據為128個byte,而key_size=1024 加密塊大小為127 byte,加密後為128個byte;
// 因此共有2個加密塊,第一個127 byte第二個為1個byte
int blockSize = cipher.getBlockSize();
// System.out.println("blockSize:"+blockSize);
int outputSize = cipher.getOutputSize(data.length);// 獲得加密塊加密後塊大小
// System.out.println("加密塊大小:"+outputSize);
int leavedSize = data.length % blockSize;
// System.out.println("leavedSize:"+leavedSize);
int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;
byte[] raw = new byte[outputSize * blocksSize];
int i = 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++;
}
return raw;
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
/**
* 解密
* @param key 解密的密鑰
* @param raw 已經加密的數據
* @return 解密後的明文
* @throws Exception
*/
@SuppressWarnings("static-access")
public byte[] decrypt(Key key, byte[] raw) throws Exception {
try {
Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(cipher.DECRYPT_MODE, key);
int blockSize = cipher.getBlockSize();
ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
int j = 0;
while (raw.length - j * blockSize > 0) {
bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
j++;
}
return bout.toByteArray();
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
/**
* 返回公鑰
* @return
* @throws Exception
*/
public RSAPublicKey getRSAPublicKey() throws Exception{
//獲取公鑰
RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();
//獲取公鑰系數(位元組數組形式)
byte[] pubModBytes = pubKey.getMolus().toByteArray();
//返回公鑰公用指數(位元組數組形式)
byte[] pubPubExpBytes = pubKey.getPublicExponent().toByteArray();
//生成公鑰
RSAPublicKey recoveryPubKey = this.generateRSAPublicKey(pubModBytes,pubPubExpBytes);
return recoveryPubKey;
}
/**
* 獲取私鑰
* @return
* @throws Exception
*/
public RSAPrivateKey getRSAPrivateKey() throws Exception{
// 獲取私鑰
RSAPrivateKey priKey = (RSAPrivateKey) keyPair.getPrivate();
// 返回私鑰系數(位元組數組形式)
byte[] priModBytes = priKey.getMolus().toByteArray();
// 返回私鑰專用指數(位元組數組形式)
byte[] priPriExpBytes = priKey.getPrivateExponent().toByteArray();
// 生成私鑰
RSAPrivateKey recoveryPriKey = this.generateRSAPrivateKey(priModBytes,priPriExpBytes);
return recoveryPriKey;
}
/**
* 測試
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
RSAUtil rsa = new RSAUtil();
String str = "天龍八部、神鵰俠侶、射鵰英雄傳白馬嘯西風";
RSAPublicKey pubKey = rsa.getRSAPublicKey();
RSAPrivateKey priKey = rsa.getRSAPrivateKey();
// System.out.println("加密後==" + new String(rsa.encrypt(pubKey,str.getBytes())));
String mw = new String(rsa.encrypt(pubKey, str.getBytes()));
System.out.println("加密後:"+mw);
// System.out.println("解密後:");
System.out.println("解密後==" + new String(rsa.decrypt(priKey,rsa.encrypt(pubKey,str.getBytes()))));
}
}