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

aes给需要传输的数据加解密,rsa给aes的key加解密;前后端需要先约定好一个密钥对儿。

生成rsa密钥对儿网址 ⬇️
http://www.metools.info/code/c80.html

~加密步骤:
  1. 生成随机16位key(如果写死会不安全,所以要动态生成)
  2. 使用rsa给key加密(加密后的rsakey需要传给后端)
  3. 使用aes(data,key)给数据加密
  4. 将rsaKey传给后端,放在请求头里或者作为另一个参数都可以
~解密步骤:
  1. 获取到后端传过来的rsaKey
  2. 使用rsa给rsaKey解密得到key
  3. 将key作为key。。。。使用aes给传输来的数据解密

基本上是上述这样。没有理论因为我不懂不好意思。。。。小小地总结了一下子对称加密和非对称加密的优缺点

二者各有千秋?所以我们一般将它们结合一下子使用。我将所有的方法放在了一份文件中,用的时候直接用在前端封装的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) => {
    // 随机16位key
    const key = getKey();
    // rsa给key加密
    const rsaKey = setRsa(key);
    // 给数据加密
    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) || ""
    };
};

/**
 * 获取随机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解密中会遇到很多解不出的情况,所以这里我们使用了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 "";
    }
}


// 额外记录一下子没有key的aes加解密方法
const key = CryptoJS.enc.Utf8.parse('aaDJL2d9DfhLZO0z');// 密钥
const iv = CryptoJS.enc.Utf8.parse('412ADDSSFA342442');// 偏移量 
// aes无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无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(); 
}  

使用页面代码

// 模拟前端给后端:一份数据,一个key
encode() {
    let { key, data } = njxEncode(this.data);
    this.keyB = key;
    this.dataB = data;

    this.decode();
},
// 模拟后端返回的解密数据
decode() {
    const {res} = njxDecode(this.dataB, this.keyB);
    this.dataA = res;
},

使用前记得先安装这俩包儿。
yarn add crypto-js
yarn add jsencrypt
用TypeScript时,给每个方法的参数添加类型即可;require是webpack方法,使用ts时需要使用import,然后会报错

ts报错儿
这时我们yarn add @types/crypto-js即可。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容