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

2023-03-14  本文已影响0人  牛会骑自行车
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');
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 = 
`-----BEGIN PRIVATE KEY-----
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==
-----END PRIVATE KEY-----
`;

/**
 * 加密
 * @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: 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)
    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) {
    var encryptedHexStr = CryptoJS.enc.Hex.parse(word)
    var srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr)
    var decrypt = CryptoJS.AES.decrypt(srcs, CryptoJS.enc.Utf8.parse(key), {
        iv: CryptoJS.enc.Utf8.parse(key),
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    })
    var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8)
    return decryptedStr.toString()
}


// 额外记录一下子没有key的aes加解密方法
// 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;
},

嗷对。。记得先install那俩那啥 crypto-js jsencrypt。很丢人哈哈哈哈哈哈哈哈

上一篇下一篇

猜你喜欢

热点阅读