aes給需要傳輸?shù)臄?shù)據(jù)加解密步藕,rsa給aes的key加解密;前后端需要先約定好一個(gè)密鑰對(duì)兒魄咕。
生成rsa密鑰對(duì)兒網(wǎng)址 ??
http://www.metools.info/code/c80.html
~加密步驟:
- 生成隨機(jī)16位key(如果寫(xiě)死會(huì)不安全,所以要?jiǎng)討B(tài)生成)
- 使用rsa給key加密(加密后的rsakey需要傳給后端)
- 使用aes(data,key)給數(shù)據(jù)加密
- 將rsaKey傳給后端磕诊,放在請(qǐng)求頭里或者作為另一個(gè)參數(shù)都可以
~解密步驟:
- 獲取到后端傳過(guò)來(lái)的rsaKey
- 使用rsa給rsaKey解密得到key
- 將key作為key。。霎终。滞磺。使用aes給傳輸來(lái)的數(shù)據(jù)解密
二者各有千秋阅茶?所以我們一般將它們結(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ò)兒
yarn add @types/crypto-js
即可。