之前一直在做公司內網(wǎng)項目,對與加密基本沒有考慮,最近看到加密的方法,在此做一個筆記,以便后面使用,
RSA加密算法簡介
SA加密算法是一種非對稱加密算法着憨。在公開密鑰加密和電子商業(yè)中RSA被廣泛使用。對極大整數(shù)做因數(shù)分解的難度決定了RSA算法的可靠性圈匆。換言之邻吭,對一極大整數(shù)做因數(shù)分解愈困難晤斩,RSA算法愈可靠焕檬。假如有人找到一種快速因數(shù)分解的算法的話,那么用RSA加密的信息的可靠性就肯定會極度下降澳泵。但找到這樣的算法的可能性是非常小的实愚。今天只有短的RSA鑰匙才可能被強力方式解破。到目前為止兔辅,世界上還沒有任何可靠的攻擊RSA算法的方式腊敲。只要其鑰匙的長度足夠長,用RSA加密的信息實際上是不能被解破的维苔。
RSA加密的java實現(xiàn)
實現(xiàn)的思路,由RSA隨機生成一對公鑰和私鑰,公鑰方到客戶端,私鑰放到服務端,發(fā)送數(shù)據(jù)的時候由公鑰對傳輸數(shù)據(jù)進行加密,然后發(fā)送給服務端,服務端用私鑰才能對數(shù)據(jù)進行解密.下面是代碼實現(xiàn)的例子
package com.yihur.demo
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
/**
* @author yihur
* @description RSA加密
* @date 2019/4/3
*/
public class MyRSAencryptionMethod {
private static Logger logger = LoggerFactory.getLogger(MyRSAencryptionMethod .class);
/**
* 用于封裝隨機產(chǎn)生的公鑰與私鑰
*
* @author yihur
* @date 2019/4/4
* @param
* @return
*/
private static Map<Integer, String> keyMap = new HashMap<>();
/**
* 測試方法
*
* @param args
* @return void
* <p>
* <p>
* 前端用crypto-js進行加密碰辅,
* npm i jsencrypt,
* 然后頁面頭引入import JSEncrypt from 'jsencrypt';
* const encrypt = new JSEncrypt();
* encrypt.setPublicKey('你的公鑰');
* password = encrypt.encrypt(‘你的密碼’);// 加密后的字符串
* @author yihur
* @date 2019/4/4
*/
public static void main(String[] args) {
//生成公鑰和私鑰
genKeyPair();
//加密字符串
String message = "df723820";
System.out.println("隨機生成的公鑰為:" + keyMap.get(0));
System.out.println("隨機生成的私鑰為:" + keyMap.get(1));
String messageEn = encrypt(message, keyMap.get(0));
System.out.println("加密后的字符串為:" + messageEn);
String messageDe = decrypt(messageEn, keyMap.get(1));
System.out.println("還原后的字符串為:" + messageDe);
}
/**
* 隨機生成密鑰對
*
* @param
* @return void
* @author yihur
* @date 2019/4/4
*/
public static void genKeyPair() {
// KeyPairGenerator類用于生成公鑰和私鑰對介时,基于RSA算法生成對象
KeyPairGenerator keyPairGen = null;
try {
keyPairGen = KeyPairGenerator.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
logger.info(e.getMessage());
}
// 初始化密鑰對生成器没宾,密鑰大小為96-1024位
assert keyPairGen != null;
keyPairGen.initialize(1024, new SecureRandom());
// 生成一個密鑰對,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私鑰
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公鑰
String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
// 得到私鑰字符串
String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
// 將公鑰和私鑰保存到Map
keyMap.put(0, publicKeyString); //0表示公鑰
keyMap.put(1, privateKeyString); //1表示私鑰
}
/**
* RSA公鑰加密
*
* @param str 加密字符串
* @param publicKey 公鑰
* @return 密文
*/
public static String encrypt(String str, String publicKey) {
//base64編碼的公鑰
byte[] decoded = Base64.decodeBase64(publicKey);
RSAPublicKey pubKey = null;
String outStr = null;
try {
pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
} catch (InvalidKeySpecException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchPaddingException | NoSuchAlgorithmException e) {
e.printStackTrace();
logger.info(e.getMessage());
}
//RSA加密
return outStr;
}
/**
* RSA私鑰解密
*
* @param str 加密字符串
* @param privateKey 私鑰
* @return 銘文
*/
public static String decrypt(String str, String privateKey) {
//64位解碼加密后的字符串
byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
//base64編碼的私鑰
byte[] decoded = Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = null;
//RSA解密
Cipher cipher = null;
String outStr = null;
try {
priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
outStr = new String(cipher.doFinal(inputByte));
} catch (InvalidKeySpecException | NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException e) {
e.printStackTrace();
logger.info(e.getMessage());
}
return outStr;
}
}
RSA加密的前端用法
前端用crypto-js進行加密沸柔,
npm i jsencrypt循衰,
然后頁面頭引入import JSEncrypt from 'jsencrypt';
const encrypt = new JSEncrypt();
encrypt.setPublicKey('你的公鑰');
password = encrypt.encrypt(‘你的密碼’);// 加密后的字符串
后續(xù)
在實際應用中RSA加密也還是遠遠不夠,一般還會加入MD5加密的方式,以及加密驗證,token等等方式作為請求連接的校驗,比如后端加密一個MD5字符串,給前端之后,前端用特定組合加上傳輸數(shù)據(jù)返回一個RSA加密的字符串,后端接收后解密,然后和自身的字符串進行對比,以確認數(shù)據(jù)來源的準確性.
這都是本人的淺淺理解,加密這一塊水深似海,我不過是看到了小小的一點,如果內容有誤歡迎各位大佬指正,謝謝.