1. 程式人生 > 其它 >RSA加密 - Vue

RSA加密 - Vue

前言

上一篇部落格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)

結果如下所示:

- End -
一個努力中的公眾號
關注一下吧
以上為本篇文章的主要內容,希望大家多提意見,如果喜歡記得點個推薦哦 作者:95.8℃ 出處:https://www.cnblogs.com/maggieq8324/ 本文版權歸作者和部落格園共有,歡迎轉載,轉載時保留原作者和文章地址即可。