最近公司進行vue項目用到RSA簽名厂抖,研究了一下網(wǎng)上的一些技術(shù)博客,發(fā)現(xiàn)都是千篇一律,而且實現(xiàn)原理示例代碼都存在或多或少的問題所以自己寫下這篇文章記錄總結(jié)一下RSA加簽榔幸、驗簽的方法愉豺,讓像我這種開發(fā)小白少走彎路篓吁。
一、RSA簽名的原理
RSA簽名需要公鑰和私鑰蚪拦,具體實現(xiàn)原理是:
1杖剪、A保留生成的私鑰冻押,將公鑰留給B;
2盛嘿、A用私鑰將數(shù)據(jù)加簽生成密文洛巢,傳給B;
3次兆、B接到數(shù)據(jù)用公鑰將數(shù)據(jù)加簽狼渊,生成密文與A傳過來的密文進行對比,如果對比的結(jié)果一致类垦,證明消息是A回復(fù)的狈邑。
二、vue項目中RSA加簽蚤认、驗簽具體實現(xiàn)步驟
1米苹、密鑰的生成
密鑰的生成有很多方法最簡單的方法是直接在網(wǎng)上搜索 “RSA密鑰生成”就可以找到專門生成RSA密鑰的網(wǎng)站。而我這里介紹的是使用 支付寶 rsa 密鑰生成工具 生成密鑰 砰琢。如圖:
2蘸嘶、簽名規(guī)則
為了保證數(shù)據(jù)的嚴謹性需要對數(shù)據(jù)進行一下處理,比如排序陪汽,或者在數(shù)據(jù)后面加上一些你與后端約定的一些代碼训唱。如圖:3、在VUE中使用jsrsasign進行簽名
1挚冤、安裝jsrsasign
jsrsasign官網(wǎng)
npm install jsrsasign --save
2况增、引入jsrsasign
因為我將加簽、驗簽封裝在了統(tǒng)一的jsrsasign.js文件中所以要在js文件中引用如下代碼
import Vue from 'vue'
import jsrsasign, { KJUR, hextob64, b64utohex } from 'jsrsasign'
Vue.prototype.$jsrsasign = jsrsasign
3训挡、加簽
/**
* RSA加簽
* @param {加簽參數(shù)} signData
*/
export const RSAEncrypt = (signData) => {
let prk = '' //私鑰
let signPrivateKey = '-----BEGIN PRIVATE KEY-----' + prk + '-----END PRIVATE KEY-----';
let data = signData
//ASCII排序 生成 bar=2&foo=1這種結(jié)構(gòu)
function sortAsc (o) {
var n = [];
for (var k in o) n.push(k);
n.sort();
for (var i = 0, str = ''; i < n.length; i++) {
var v = o[n[i]];
if (v) {
if ({}.toString.call(v) == '[object Object]')
v = sortAsc(v);
else if ({}.toString.call(v) == '[object Array]')
v = JSON.stringify(v).replace(/:/g, '=');
}
str += '&' + n[i] + '=' + v;
}
return str.slice(1);
}
// 參數(shù)
let data1 = sortAsc(data) + 'zaq1' // sortAsc(data) 'zaq1'為與后端約定好的參數(shù)值
let sig = new KJUR.crypto.Signature({ "alg": "SHA1withRSA" });//創(chuàng)建sig對象并指定算法名稱(SHA1withRSA)算法要與后端約定好
sig.init(signPrivateKey);//初始化實例
sig.updateString(data1)//更新簽名數(shù)據(jù)
let sign = jsrsasign.hextob64(sig.sign())//簽名得到十六進制密文
return sign
}
4澳骤、驗簽
/**
* RSA驗簽
* @param {加簽的數(shù)據(jù)} signData
* @param {加簽之后得到的簽文} data
*/
export const RSADecrypt = (signData, data) => {
//ASCII排序 生成 bar=2&foo=1這種結(jié)構(gòu)
function sortAsc (o) {
var n = [];
for (var k in o) n.push(k);
n.sort();
for (var i = 0, str = ''; i < n.length; i++) {
var v = o[n[i]];
if (v) {
if ({}.toString.call(v) == '[object Object]')
v = sortAsc(v);
else if ({}.toString.call(v) == '[object Array]')
v = JSON.stringify(v).replace(/:/g, '=');
}
str += '&' + n[i] + '=' + v;
}
return str.slice(1);
}
let newSign1 = sortAsc(signData) + 'zaq1'// 'zaq1'為與后端約定好的參數(shù)值
try {
let pk = ''//公鑰
let signPublicKey = '-----BEGIN PUBLIC KEY-----' + pk + '-----END PUBLIC KEY-----';
let sig2 = new KJUR.crypto.Signature({ "alg": "SHA1withRSA" });//創(chuàng)建sig2對象并指定算法名稱(SHA1withRSA)
sig2.init(signPublicKey);//初始化實例
sig2.updateString(newSign1);//更新簽名數(shù)據(jù)
let result = sig2.verify(b64utohex(data));//進行十六進制字符串的驗簽
return result;
} catch (e) {
console.error(e);
}
}
以上便是我對RSA加簽驗簽的小結(jié),希望可以幫助到需要的人澜薄。