古詩詞大全網 - 個性簽名 - 如何用javascript實現rsa加密解密

如何用javascript實現rsa加密解密

具體實現思路如下:

1。服務器生成公鑰和私鑰並保存它們。

2。客戶端請求登錄頁面後,它會隨機生成壹個字符串。

3。然後將這個隨機串作為密鑰加密密碼,然後用從服務器獲取的公鑰對生成的隨機串進行加密。

4。這兩個密文傳輸到服務器,服務器用私鑰解隨機串,再用這個私鑰解加密的密文。

其中壹個關鍵是求解服務器的公鑰,這個公鑰傳輸給客戶端。客戶端用這個公鑰加密字符串後,就可以在服務器端用私鑰解決了。

本文就是為了實現這壹步。

加密算法是RSA:

1。服務器上的RSA?Java實現。

/**?

*?

*/?

包裹?com . sun soft . struts . util;?

進口?Java . io . bytearrayoutputstream;?

進口?Java . io . file inputstream;?

進口?Java . io . file output stream;?

進口?Java . io . objectinputstream;?

進口?Java . io . object output stream;?

進口?Java . math . big integer;?

進口?Java . security . key factory;?

進口?Java . security . key pair;?

進口?Java . security . key pair generator;?

進口?Java . security . nosuchalgorithm exception;?

進口?Java . security . private key;?

進口?Java . security . public key;?

進口?Java . security . securerandom;?

進口?Java . security . interfaces . rsaprivatekey;?

進口?Java . security . interfaces . RSA public key;?

進口?Java . security . spec . invalidkeyspecexception;?

進口?Java . security . spec . rsaprivatekeyspec;?

進口?Java . security . spec . rsapapublickeyspec;?

進口?javax . crypto . cipher;?

/**?

*?RSA?工具類。提供對等的加密、解密和密鑰生成方法。?

*?妳需要在http://www.bouncycastle.org下載BC prov-JDK 14-123 . jar。?

*?

*/?

公共?班級?RSAUtil?{?

/**?

*?*?生成密鑰對?*?

*?

*?@回歸?KeyPair?*?

*?@throws?加密異常?

*/?

公共?靜電?KeyPair?generateKeyPair()?摔投?例外?{?

試試?{?

KeyPairGenerator?keyPairGen?=?keypairgenerator . getinstance(" RSA ",

新的?org . bouncy castle . JCE . provider . bouncy castle provider());?

決賽?int?KEY_SIZE?=?1024;//?沒什麽好說的。這個值與塊加密的大小有關,可以改變,但不能太大,否則效率低?

keyPairGen.initialize(KEY_SIZE,?新的?SecureRandom());?

KeyPair?keyPair?=?keypairgen . generatekeypair();?

saveKeyPair(密鑰對);?

回歸?密鑰對;?

}?接住?(例外?e)?{?

扔?新的?異常(e . getmessage());?

}?

}?

公共?靜電?KeyPair?getKeyPair()拋出?異常{?

FileInputStream?fis?=?新的?file inputstream(" C:/RSA key . txt ");?

ObjectInputStream?oos?=?新的?ObjectInputStream(fis);?

KeyPair?kp=?(KeyPair)?OOS . read object();?

OOS . close();?

fis . close();?

回歸?KP;?

}?

公共?靜電?作廢?saveKeyPair(KeyPair?kp)投?異常{?

FileOutputStream?fos?=?新的?file output stream(" C:/RSA key . txt ");?

ObjectOutputStream?oos?=?新的?ObjectOutputStream(fos);?

//生成密鑰?

OOS . writeobject(KP);?

OOS . close();?

fos . close();?

}?

/**?

*?*?生成公鑰?*?

*?

*?@param?模數?*?

*?@param?publicExponent?*?

*?@回歸?RSAPublicKey?*?

*?@throws?例外?

*/?

公共?靜電?RSAPublicKey?generateRSAPublicKey(byte[]?模數,?

byte[]?publicExponent)?摔投?例外?{?

KeyFactory?keyFac?=?null?

試試?{?

keyFac?=?KeyFactory.getInstance("RSA ",

新的?org . bouncy castle . JCE . provider . bouncy castle provider());?

}?接住?(NoSuchAlgorithmException?ex)?{?

扔?新的?異常(ex . getmessage());?

}?

RSAPublicKeySpec?pubKeySpec?=?新的?RSAPublicKeySpec(新?BigInteger(?

模數),?新的?big integer(public index));?

試試?{?

回歸?(RSAPublicKey)?keyfac . generate public(pubkey spec);?

}?接住?(InvalidKeySpecException?ex)?{?

扔?新的?異常(ex . getmessage());?

}?

}?

/**?

*?*?生成私鑰?*?

*?

*?@param?模數?*?

*?@param?privateExponent?*?

*?@回歸?RSAPrivateKey?*?

*?@throws?例外?

*/?

公共?靜電?RSAPrivateKey?generateRSAPrivateKey(byte[]?模數,?

byte[]?privateExponent)?摔投?例外?{?

KeyFactory?keyFac?=?null?

試試?{?

keyFac?=?KeyFactory.getInstance("RSA ",

新的?org . bouncy castle . JCE . provider . bouncy castle provider());?

}?接住?(NoSuchAlgorithmException?ex)?{?

扔?新的?異常(ex . getmessage());?

}?

RSAPrivateKeySpec?priKeySpec?=?新的?RSAPrivateKeySpec(新?BigInteger(?

模數),?新的?big integer(private index));?

試試?{?

回歸?(RSAPrivateKey)?key fac . generate private(prikey spec);?

}?接住?(InvalidKeySpecException?ex)?{?

扔?新的?異常(ex . getmessage());?

}?

}?

/**?

*?*?加密?*?

*?

*?@param?鑰匙?

*加密密鑰?*?

*?@param?數據?

*要加密的明文數據?*?

*?@回歸?加密數據?*?

*?@throws?例外?

*/?

公共?靜電?byte[]?加密(PublicKey?pk,?byte[]?數據)?摔投?例外?{?

試試?{?

密碼?密碼?=?Cipher.getInstance("RSA ",

新的?org . bouncy castle . JCE . provider . bouncy castle provider());?

cipher.init(密碼。加密模式?PK);?

int?blockSize?=?cipher . get blocksize();//?獲取加密後的塊大小,比如加密前的數據是128 byte,key_size=1024?

//?加密塊大小是127?

//?Byte,加密後為128字節;所以* * *有兩個加密塊,第壹個是127?

//?第二個字節是1字節?

int?outputSize?=?cipher . getoutputsize(data . length);//?加密後得到加密塊大小?

int?leavedSize?=?數據長度?%?blockSize?

int?blocksSize?=?leavedSize?!=?0數據長度?/?blockSize?+?1?

:?數據長度?/?blockSize?

byte[]?生的?=?新的?byte[outputSize?*?blocksSize];?

int?我?=?0;?

什麽時候?(數據.長度?-?我?*?blockSize?& gt?0)?{?

如果?(數據.長度?-?我?*?blockSize?& gt?blockSize)?

cipher.doFinal(data,?我?*?塊大小,?塊大小,?生的?我?

*?output size);?

不然呢?

cipher.doFinal(data,?我?*?塊大小,?數據長度?-?我?

*?塊大小,?生的?我?*?output size);?

//?doUpdate方法在這裏不可用。查了壹下源代碼,發現每次doUpdate之後除了把byte[]放進去之外,並沒有什麽實際動作?

//?ByteArrayOutputStream,以及所有byte[] []都在doFinal結束時加密,但此時加密塊大小很可能已經超過?

//?OutputSize,所以我們必須使用dofinal方法。?

i++;?

}?

回歸?生的;?

}?接住?(例外?e)?{?

扔?新的?異常(e . getmessage());?

}?

}?

/**?

*?*?解密?*?

*?

*?@param?鑰匙?

*解密密鑰?*?

*?@param?生的?

*加密數據?*?

*?@回歸?解密明文?*?

*?@throws?例外?

*/?

公共?靜電?byte[]?解密(PrivateKey?pk,?byte[]?raw)?摔投?例外?{?

試試?{?

密碼?密碼?=?Cipher.getInstance("RSA ",

新的?org . bouncy castle . JCE . provider . bouncy castle provider());?

cipher.init(密碼。解密模式,?PK);?

int?blockSize?=?cipher . get blocksize();?

ByteArrayOutputStream?布特?=?新的?ByteArrayOutputStream(64);?

int?j?=?0;?

什麽時候?(raw .長度?-?j?*?blockSize?& gt?0)?{?

bout.write(cipher.doFinal(raw,j?*?塊大小,?block size));?

j++;?

}?

回歸?bout . tobytearray();?

}?接住?(例外?e)?{?

扔?新的?異常(e . getmessage());?

}?

}?

/**?

*?*?*?

*?

*?@param?args?*?

*?@throws?例外?

*/?

公共?靜電?作廢?main(String[]?args)?摔投?例外?{?

RSAPublicKey?rsap?=?(RSAPublicKey)?RSAUtil.generateKeyPair()。getPublic();?

字符串?測試?=?“餵?世界”;?

byte[]?en_test?=?encrypt(getKeyPair()。getPublic()、test . getbytes());?

byte[]?de_test?=?解密(getKeyPair()。getPrivate(),en _ test);?

System.out.println(新?string(de _ test));?

}?

} 2.測試頁面:

IndexAction.java