vue ---- 使用rsa和aes給接口加解密

aes給需要傳輸?shù)臄?shù)據(jù)加解密步藕,rsa給aes的key加解密;前后端需要先約定好一個(gè)密鑰對(duì)兒魄咕。

生成rsa密鑰對(duì)兒網(wǎng)址 ??
http://www.metools.info/code/c80.html

~加密步驟:
  1. 生成隨機(jī)16位key(如果寫(xiě)死會(huì)不安全,所以要?jiǎng)討B(tài)生成)
  2. 使用rsa給key加密(加密后的rsakey需要傳給后端)
  3. 使用aes(data,key)給數(shù)據(jù)加密
  4. 將rsaKey傳給后端磕诊,放在請(qǐng)求頭里或者作為另一個(gè)參數(shù)都可以
~解密步驟:
  1. 獲取到后端傳過(guò)來(lái)的rsaKey
  2. 使用rsa給rsaKey解密得到key
  3. 將key作為key。。霎终。滞磺。使用aes給傳輸來(lái)的數(shù)據(jù)解密

基本上是上述這樣。沒(méi)有理論因?yàn)槲也欢缓靡馑祭嘲;骼А!9阃埂P⌒〉乜偨Y(jié)了一下子對(duì)稱(chēng)加密和非對(duì)稱(chēng)加密的優(yōu)缺點(diǎn)

二者各有千秋阅茶?所以我們一般將它們結(jié)合一下子使用。我將所有的方法放在了一份文件中谅海,用的時(shí)候直接用在前端封裝的axios中就行啦~

const CryptoJS = require('crypto-js'); // js
// import CryptoJS from 'crypto-js' // ts
import JSEncrypt from 'jsencrypt';

// rsa公鑰:加密
const rsaPublicKey = `MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxpNjffeqjUrZfz2HiaTo
6WdPqlUcyqrsykyrzynDk6mXknIybijcwuX7G7OHlUV0kbs7XDjyrtsmTj3ezhGd
OvmJn7q4swddgiDGo0mCCXa2hf7VCukmptJccRsxZLOuf20vu/iAeYtIkQUZJp8w
Se7IOkIcn7aX+zcQPls7OOQI37cCJx+Mxr08Sg+H6R+uo3naFyOaGCirlJc58NfH
r1oOmuSCcDRSxWatIaqTGpFC+jnU8LbNZJyUXaCGC4FETGuzfc01qd4CfO/sKuPa
3NoF94+/AQPnd/QOdy654C6WeuYO8SPqRCPEnpNd05CeVSVfT9GGLfpbz3ARrhUp
0wIDAQAB`;
// rsa私鑰:解密
const rsaPrivateKey = 
`MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDGk2N996qNStl/
PYeJpOjpZ0+qVRzKquzKTKvPKcOTqZeScjJuKNzC5fsbs4eVRXSRuztcOPKu2yZO
Pd7OEZ06+YmfurizB12CIMajSYIJdraF/tUK6Sam0lxxGzFks65/bS+7+IB5i0iR
BRkmnzBJ7sg6Qhyftpf7NxA+Wzs45AjftwInH4zGvTxKD4fpH66jedoXI5oYKKuU
lznw18evWg6a5IJwNFLFZq0hqpMakUL6OdTwts1knJRdoIYLgURMa7N9zTWp3gJ8
7+wq49rc2gX3j78BA+d39A53LrngLpZ65g7xI+pEI8Sek13TkJ5VJV9P0YYt+lvP
cBGuFSnTAgMBAAECggEAA+MwyG+HzDpR5bbLp3suABvAqIIADUupVRCJMIYNyR9B
02Ee8Z8lKz+bWeB64AY7EPtMXzLSNXAe4Ns/OGOJ43StKA5cvUyAnSKNIPc4b3z+
d8MUYqFL22o02xYAMot9+AqoK5Li2P5MDmK+Kk5lgJ0HGHTg4JOPiCB81eutTiDH
4A7XsqCesLMYHTLLtEHmRLQVq40BVobS1oh1j9zDmHmC7ygMEZHHFD+NZhM++jkS
qZXFrMgI4yMFS0nw9SmkTtYtIigXrqHcLsIN+kTgrpgTsjDwARmnesUr3Pb3XwO4
YAPykQraa0g60nGJaZw5jCQ+S3IpdSPjf0djencUyQKBgQDutLqx3emyfw8gGFG3
e4AX/Y9uyTbRmZtSYwObP+bDJ702EXhVeu+3y9QA3YRCB8BwYf4YIBSYSaaaErGO
WByW2GNhX5KBMmAZ2V8EafSmFmXCHcki9BbZAcoYH98hK8K8NLxm+AVvY/81Sa34
ESBnoeWQRjO1UoZ3bA9e93nq1wKBgQDU9l2I3AC2sxJQA6rgx332TabnFlH34H2D
OUyRQiLPNPwkBruLadNXVAjd0xXxzZFk640YSjTuCZ6yMyRkn+tEmnIUMlZFx/6k
38cIA2hVAV1CzK4HMRwHytXVMQjlISXwRn9Ww/Wu7S63Go+gl5x6d9SSpCm1D9xR
5eUJVus1ZQKBgH0B9reJQIay1af4NGtDaPynVEMvat7vc5D8u3nFSEMxf3xeP8d8
PyfgvaDKYSX3S0dPejMGMeLixzXuzj9+U1KH9dubomy4he1jkcgM+Qs1tYqn8Jq2
e3Sf5EcoAcEsWqoXcAb4olgIZTFx6YJ87Zx4A3G/4fp2QmcuFwqjzZw3AoGAY0+o
esQtyQVlCs9LBpvBT/USWj18aB3WKjW0USEIXpyU4LALEY5+MgFMSTXAzAxTOz7l
g2hHmqH90Zgr5oj1C/8CKAz5Un1bcMOyazg7lTiXpykQFuZ97dxXL544SbHVoWEe
zPWBQtv0pwrJ49gP7sSm6uOHV5pX4hFVZ6+S7EkCgYBIahpocIdQmQeBRpcSPq7q
Rwfyd/EQ8CrLM7v4hXAMGeUDi1BGy+J98ZBLVFMm1Hs4iS2mBEBdRCRNXLwJIOwk
3Ug0Alt6/5hYtsGA6PLfR96/v1A8e61rqt8v3cvcd8SsFmPNZVGqke7LNE+N2ywM
NBpJQ7zSda3WQ2La0B1x0A==`;

/**
 * 加密
 * @param {*} word 
 * @param {*} key 
 */
export const njxEncode = (word) => {
    // 隨機(jī)16位key
    const key = getKey();
    // rsa給key加密
    const rsaKey = setRsa(key);
    // 給數(shù)據(jù)加密
    word = JSON.stringify(word);
    const data = setAes(word, key);
    return {
        key: rsaKey,
        data,
    }
}

/**
 * 解密
 * @param {*} word 
 * @param {*} key 
 */
export const njxDecode = (word, rsaKey) => {
    const key = getRsa(rsaKey);
    word = getAes(word, key);

    return {
        res: key && word && JSON.parse(word) || ""
    };
};

/**
 * 獲取隨機(jī)16位key
 * @param {*} len
 * @param {*} radix
 * @returns
 */
function getKey(len = 16, radix = 16) {
    var chars =
        '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
    var uuid = []
    var i
    radix = radix || chars.length

    if (len) {
        // Compact form
        for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)]
    } else {
        // rfc4122, version 4 form
        var r

        // rfc4122 requires these characters
        uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
        uuid[14] = '4'

        // Fill in random data.  At i==19 set the high bits of clock sequence as
        // per rfc4122, sec. 4.1.5
        for (i = 0; i < 36; i++) {
            if (!uuid[i]) {
                r = 0 | (Math.random() * 16)
                uuid[i] = chars[i === 19 ? (r & 0x3) | 0x8 : r]
            }
        }
    }
    return uuid.join('')
}

/**
 * rsa加密
 * @param {*} key
 * @returns
 */
function setRsa(key) {
    const jsencrypt = new JSEncrypt()
    jsencrypt.setPublicKey(rsaPublicKey)
    return jsencrypt.encrypt(key)
}
/**
 * rsa解密
 * @param {*} key
 * @returns
 */
function getRsa(key) {
    const decrypt = new JSEncrypt()
    decrypt.setPrivateKey(rsaPrivateKey)
    // 下文的""為了防止存于localStorage中的信息被不小心損壞
    return decrypt.decrypt(key) || ""
}

/**
 * aes加密
 * @param {*} word 
 * @param {*} key 
 * @returns 
 */
function setAes(word, key) {
    var srcs = CryptoJS.enc.Utf8.parse(word)
    var encrypted = CryptoJS.AES.encrypt(srcs, CryptoJS.enc.Utf8.parse(key), {
        iv: CryptoJS.enc.Utf8.parse(key),
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    })
    return encrypted.ciphertext.toString().toUpperCase()
}
/**
 * aes解密
 * @param {*} word 
 * @param {*} key 
 * @returns 
 */
function getAes(word, key) {
    // 在aes解密中會(huì)遇到很多解不出的情況脸哀,所以這里我們使用了try catch
    try{
        var encryptedHexStr = CryptoJS.enc.Hex.parse(word)
        var srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr)
        const iv = CryptoJS.enc.Utf8.parse(key);
        var decrypt = CryptoJS.AES.decrypt(srcs, iv, {
            iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        })
        var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
        return decryptedStr.toString();
    } 
    catch{
        return "";
    }
}


// 額外記錄一下子沒(méi)有key的aes加解密方法
const key = CryptoJS.enc.Utf8.parse('aaDJL2d9DfhLZO0z');// 密鑰
const iv = CryptoJS.enc.Utf8.parse('412ADDSSFA342442');// 偏移量 
// aes無(wú)key加密
export const aesEncode = (word) => {     
    let srcs = CryptoJS.enc.Utf8.parse(word);     
    let encrypted = CryptoJS.AES.encrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });     
    return encrypted.ciphertext.toString().toUpperCase(); 
}  
// aes無(wú)key解密
export const aesDecode = (word) => {   
    let encryptedHexStr = CryptoJS.enc.Hex.parse(word);     
    let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);     
    let decrypt = CryptoJS.AES.decrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });     
    let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);    
    return decryptedStr.toString(); 
}  

使用頁(yè)面代碼

// 模擬前端給后端:一份數(shù)據(jù),一個(gè)key
encode() {
    let { key, data } = njxEncode(this.data);
    this.keyB = key;
    this.dataB = data;

    this.decode();
},
// 模擬后端返回的解密數(shù)據(jù)
decode() {
    const {res} = njxDecode(this.dataB, this.keyB);
    this.dataA = res;
},

使用前記得先安裝這倆包兒胁赢。
yarn add crypto-js
yarn add jsencrypt
用TypeScript時(shí)企蹭,給每個(gè)方法的參數(shù)添加類(lèi)型即可;require是webpack方法智末,使用ts時(shí)需要使用import谅摄,然后會(huì)報(bào)錯(cuò)

ts報(bào)錯(cuò)兒
這時(shí)我們yarn add @types/crypto-js即可。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末系馆,一起剝皮案震驚了整個(gè)濱河市送漠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌由蘑,老刑警劉巖闽寡,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異尼酿,居然都是意外死亡爷狈,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén)裳擎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)涎永,“玉大人,你說(shuō)我怎么就攤上這事鹿响∠畚ⅲ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵惶我,是天一觀的道長(zhǎng)妈倔。 經(jīng)常有香客問(wèn)我,道長(zhǎng)绸贡,這世上最難降的妖魔是什么盯蝴? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任毅哗,我火速辦了婚禮,結(jié)果婚禮上结洼,老公的妹妹穿的比我還像新娘黎做。我一直安慰自己,他們只是感情好松忍,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布蒸殿。 她就那樣靜靜地躺著,像睡著了一般鸣峭。 火紅的嫁衣襯著肌膚如雪宏所。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,158評(píng)論 1 308
  • 那天摊溶,我揣著相機(jī)與錄音爬骤,去河邊找鬼。 笑死莫换,一個(gè)胖子當(dāng)著我的面吹牛霞玄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拉岁,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼坷剧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了喊暖?” 一聲冷哼從身側(cè)響起惫企,我...
    開(kāi)封第一講書(shū)人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎陵叽,沒(méi)想到半個(gè)月后狞尔,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡巩掺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年偏序,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胖替。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡禽车,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出刊殉,到底是詐尸還是另有隱情,我是刑警寧澤州胳,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布记焊,位于F島的核電站,受9級(jí)特大地震影響栓撞,放射性物質(zhì)發(fā)生泄漏遍膜。R本人自食惡果不足惜碗硬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瓢颅。 院中可真熱鬧恩尾,春花似錦、人聲如沸挽懦。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)信柿。三九已至冀偶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渔嚷,已是汗流浹背进鸠。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留形病,地道東北人客年。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像漠吻,于是被迫代替她去往敵國(guó)和親量瓜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容