RSA加密 - Vue
阿新 • • 發佈:2021-07-05
前言
上一篇部落格RSA加密 - Java實現了Java
版的RSA
公鑰加密-私鑰解密,私鑰加密-公鑰解密,這篇部落格實現Vue
下的加解密,記錄兩種前後端下加解密的場景
- 前端公鑰加密 - 後端私鑰解密
- 後端私鑰加密 - 前端公鑰解密
前端公鑰加密-後端私鑰解密
這種情況較為簡單,是通用的做法
- 安裝
jsencrypt
npm install jsencrypt
RSAEncryption.js
/** * 非對稱加密-RSA * 前端公鑰加密 - 後端私鑰解密 * */ import JSEncrypt from 'jsencrypt/bin/jsencrypt' // 這裡的公鑰在Java端生成 const PUBLIC_KEY = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaaI4MBywkCjIppZnraqN3pbrcZTq/t0+aMBo8K3pK9BDD6XkM6N2Yfcva7BSFbUWuAcI7piXak0UKn9CElDuhNzUSgQn4IXKxIt3Iva5cV83qYumj+0yRjjLT8Muu1Y1rgBZjY9oBwhVoV+Twg25+UJ+6Q6HM4xTwQQJDoyy4jwIDAQAB'; // 注:正常情況下私鑰並不會記錄在前端,這裡使用私鑰解密只是記錄私鑰解密方法 const PRIVATE_KEY = 'MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJpojgwHLCQKMimlmetqo3elutxlOr+3T5owGjwrekr0EMPpeQzo3Zh9y9rsFIVtRa4BwjumJdqTRQqf0ISUO6E3NRKBCfghcrEi3ci9rlxXzepi6aP7TJGOMtPwy67VjWuAFmNj2gHCFWhX5PCDbn5Qn7pDoczjFPBBAkOjLLiPAgMBAAECgYBnBBKhG7frY5IMDxwd4Euna767hB4qAlbte+JE+ozgrOzyiDXm0wXk0yjKqm8WhczTRwEbYsImjdKmP/GSQoN1AU7yEzM8j0Jgq46m9ZVrHhu2NpuZpr+XueWnA6FNz6tybBgcCwA4t8dvfbOrvjqhrCu01O1xWIpjronyFBN4IQJBAPGuF58xjXyANnp5YU8NhUQ73tTIveRlOpMXDSYkf9lWG26XIGUIsTe0f5jssiNmYtxG+lUm9LLfZgOLcrVkDZ0CQQCjjrBNMXub49efVTCg+nCGT2QXW2BHg/qs5vu8Y34LUHoD/hoEJ+AOWOdnhpRoYOpBwJAm3Gu4a1VmZGGafp0bAkAdfY3aWhSWtZpwNXF/UPoLCnc1Zc1uGkAchLqRBfEn1w7/3qcQTRA66OaNBYzzLuIvWOXhECDZ1tK+6fw0UCItAkAOLibW6n1fDKf7JnWq30u2OVfiNofoa2bmarhUowOgk3+grP0wcwyX8dlOPnrLeeuVe86DsASe3p9u2zEjJesVAkEAhkLiv4TXrC1QlJl7ghksUfFmdT7M4Zxlzj10ConMgq68HkLdmn2nNLsjhUHGwJe3EqM6aozn4zw/Z7uPIT9Fsw=='; export const RSAENCRY = { /** * 公鑰加密 * @param val 需要加密的字串 * @return string 返回加密結果 */ encryptByPublicKey: function (val = '') { if(val === ''){ return ''; } let encryptor = new JSEncrypt() // 新建JSEncrypt物件 encryptor.setPublicKey(PUBLIC_KEY) // 設定公鑰 return encryptor.encrypt(val) // 對需要加密的資料進行加密 }, /** * 私鑰解密 * @param val * @returns {string|false|null|PromiseLike<ArrayBuffer>} */ decryptByPrivateKey: function (val = '') { if(val === ''){ return ''; } let decrypt = new JSEncrypt() // 新建JSEncrypt物件 decrypt.setPrivateKey(PRIVATE_KEY) // 設定私鑰 return decrypt.decrypt(val) // 對需要解密的資料進行解密 } }
- 驗證加解密
import { RSAENCRY } from "../utils/RSAEncryption" let data = "RSA encrypt!"; let encryptDataByPublicKey = RSAENCRY.encryptByPublicKey(data); console.log("encryptDataByPublicKey: ", encryptDataByPublicKey) let decryptDataByPrivateKey = RSAENCRY.decryptByPrivateKey(encryptDataByPublicKey); console.log("decryptDataByPrivateKey: ", decryptDataByPrivateKey)
- 結果如下
ok,如圖所示,已經實現了常規的前端公鑰加密,後端私鑰解密
後端私鑰加密 - 前端公鑰解密
這種情況有點牽強,原因是不想將私鑰記錄在前端,所以由後端私鑰加密-前端公鑰來解密,後端私鑰加密的內容RSA加密 - Java中有記錄,這裡不再重複,要實現前端公鑰解密需要修改配置檔案中的內容
- 從
node-modules
中複製jsencrypt
,這裡我複製到了src/libs
目錄下
- 修改
src/libs/jsencrypt/bin/jsencrypt.js
1. 修改 RSAKey.prototype.decrypt 中 this.doPrivate(c) 為 this.doPublic(c); RSAKey.prototype.decrypt = function (ctext) { var c = parseBigInt(ctext, 16); var m = this.doPublic(c); //var m = this.doPrivate(c); if (m == null) { return null; } return pkcs1unpad2(m, (this.n.bitLength() + 7) >> 3); }; 2. 修改 pkcs1unpad2 註釋程式碼 function pkcs1unpad2(d, n) { var b = d.toByteArray(); var i = 0; while (i < b.length && b[i] == 0) { ++i; } // 註釋該處程式碼 // if (b.length - i != n - 1 || b[i] != 2) { // return null; // } ++i; while (b[i] != 0) { if (++i >= b.length) { return null; } } var ret = ""; while (++i < b.length) { var c = b[i] & 255; if (c < 128) { // utf-8 decode ret += String.fromCharCode(c); } else if ((c > 191) && (c < 224)) { ret += String.fromCharCode(((c & 31) << 6) | (b[i + 1] & 63)); ++i; } else { ret += String.fromCharCode(((c & 15) << 12) | ((b[i + 1] & 63) << 6) | (b[i + 2] & 63)); i += 2; } } return ret; }
RSADecryption.js
/**
* 非對稱加密-RSA
* 後端私鑰加密 - 前端公鑰解密
*/
import JSEncrypt from '../libs/jsencrypt/bin/jsencrypt'
const PUBLICKEY = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaaI4MBywkCjIppZnraqN3pbrcZTq/t0+aMBo8K3pK9BDD6XkM6N2Yfcva7BSFbUWuAcI7piXak0UKn9CElDuhNzUSgQn4IXKxIt3Iva5cV83qYumj+0yRjjLT8Muu1Y1rgBZjY9oBwhVoV+Twg25+UJ+6Q6HM4xTwQQJDoyy4jwIDAQAB';
export const RSADECRY = {
/**
* 公鑰解密
* @param secretWord
* @returns {解密|string|false|PromiseLike<ArrayBuffer>}
*/
decryptByPublicKey: function (val = '') {
if (val === '') {
return '';
}
let encryptor = new JSEncrypt();
encryptor.setPublicKey(PUBLICKEY);
//使用公鑰對私鑰加密後的資料解密
return encryptor.decrypt(val);
}
}
- 呼叫後端encryByPrivateKey函式生成私鑰加密密文
String data = "RSA encrypt!";
String encryDataByPrivateKey = encryptByPrivateKey(data);
System.out.println("encryDataByPrivateKey: " + encryDataByPrivateKey);
結果如下所示:
- 前端公鑰解密呼叫
import { RSADECRY } from "../utils/RSADecryption"
let decryptData = "AwovsO+xeiFSQe6mN9RRCz3FFlMXdCMcrqbNChsc7PbMfCxSHpKWIHQ2IJ/tw8mFsuX84r7TSVhYXB9ATA7nqWxMnKJgkPu+nFXeXSnApjce0MjFtjLpl9wrklVrOL6L0cmzu3DthC44Opwj5EVWF9tjiH7YdKFVK/Q5HVPKcZk=";
let decryptDataByPublicKey = RSADECRY.decryptByPublicKey(decryptData);
console.log("decryptDataByPublicKey: ", decryptDataByPublicKey)
結果如下所示: