现在公司对前后端数据传递的严密性严格要求,原先的md5容易被破解,这次用了aes 加密内容,rsa加密aes的秘钥
AES 简介
AES 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。
RSA简介
RSA是一种公钥密码算法,它的名字是由它的三位开发者,即Ron Rivest、Adi Shamir 和 Leonard Adleman 的姓氏的首字母组成的。RSA可以被用于公钥密码和数字签名。RSA是被研究得最广泛的公钥算法,从提出到现在已近三十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。1983年麻省理工学院在美国为RSA算法申请了专利。
由于rsa对数据长度有限制,用它来加密aes的秘钥是个方法
开始我们的代码展示
- axios封装请求,将数据加密
const request = function(url, data, cover) {
const objTemp = {}
// 数据对象结构 值逐一加密
for (const key in data) {
objTemp[key] = Aes.encrypt(data[key], AesKey)
}
data = objTemp
// 密钥加密
data.aesKey = Rsa.rsaPublicData(AesKey)
let requestStructure = {
method: 'post',
url,
headers: {
'Content-Type': 'multipart/form-data'
},
// data值变成formData格式,看下面的方法
data: toFormdata(data)
}
isObject(cover) && (requestStructure = merge(requestStructure, cover))
return service(requestStructure)
}
export function toFormdata(value) {
if (isObject(value)) {
let formData = new FormData()
Object.keys(value).forEach(key => {
const item = value[key]
if (isObject(item)) {
formData.append(key, JSON.stringify(item))
}
else if (Array.isArray(item)) {
if (item[0] && item[0] instanceof File) {
item.forEach(itemValue => {
formData.append(key, itemValue)
})
} else {
formData.append(key, JSON.stringify(item))
}
}
else if (item === undefined) {
// Do nothing
} else {
formData.append(key, item)
}
})
return formData
} else {
return
}
}
- axios响应拦截里解密
service.interceptors.response.use(
response => {
const res = response.data
const state = parseInt(res.state)
if (res.data) {
// aes解密
res.data = JSON.parse(Aes.decrypt(response.data.data, AesKey))
}
if (response.config.responseType === 'arraybuffer' || response.config.notCheck) {
return finalReturn(response)
}
if (state === 1000) {
if (!res.success) { // 成功请求,参数错误返回错误信息
Message({
message: res.message || res.msg || 'Error',
type: 'error',
duration: 5 * 1000
})
}
return response
} else {
Message({
message: res.message || res.msg || 'Error',
type: 'error',
duration: 5 * 1000
})
const error = {
'错误URL': response.config.url,
'状态码': response.request.status,
'返回数据': response.request.response
}
return new Error(JSON.stringify(error, null, '\t'))
}
},
error => {
return Promise.reject(error)
}
)
- aes加密方法
import CryptoJS from 'crypto-js'
export default {
// 随机生成指定数量的16进制key
generatekey(num) {
const library = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
let key = ''
for (var i = 0; i < num; i++) {
const randomPoz = Math.floor(Math.random() * library.length)
key += library.substring(randomPoz, randomPoz + 1)
}
return key
},
// 加密
encrypt(word, keyStr) {
keyStr = keyStr || 'OeJ1iyRnFQ54g0ex' // 判断是否存在ksy,不存在就用定义好的key
if (typeof (word) !== 'string') {
word = JSON.stringify(word);
}
var key = CryptoJS.enc.Utf8.parse(keyStr)
var srcs = CryptoJS.enc.Utf8.parse(word)
var encrypted = CryptoJS.AES.encrypt(srcs, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
return encrypted.toString()
},
// 解密
decrypt(word, keyStr) {
keyStr = keyStr || 'OeJ1iyRnFQ54g0ex'
var key = CryptoJS.enc.Utf8.parse(keyStr)
var decrypt = CryptoJS.AES.decrypt(word, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
return CryptoJS.enc.Utf8.stringify(decrypt).toString()
}
}
- rsa加密方法
/* 产引入jsencrypt实现数据RSA加密 */
import JSEncrypt from 'jsencrypt' // 处理长文本数据时报错 jsencrypt.js Message too long for RSA
/* 产引入encryptlong实现数据RSA加密 */
import Encrypt from 'encryptlong' // encryptlong是基于jsencrypt扩展的长文本分段加解密功能。
// 公钥key
const publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCCxAla/lvxNMgOQ+Zfgl+nEBi+nlUZK/zdsZmDZcapzyhBlH+yEMXGxqij6H8FjItGEhYKRf5ZW7OlrBc1BSChPxkplda/lkRSnbwtEENvA8+K6fu87geMSBGNjigjHjEqzT5coFPLaDCMpvvvOmL7nPzzmm9L/QyIY9Y+kYlpmQIDAQAB'
export default {
/* JSEncrypt加密 */
rsaPublicData(data) {
var jsencrypt = new JSEncrypt()
jsencrypt.setPublicKey(publicKey)
// 如果是对象/数组的话,需要先JSON.stringify转换成字符串
var result = jsencrypt.encrypt(data)
return result
},
/* JSEncrypt解密 */
rsaPrivateData(data) {
var jsencrypt = new JSEncrypt()
jsencrypt.setPrivateKey(privateKey)
// 如果是对象/数组的话,需要先JSON.stringify转换成字符串
var result = jsencrypt.encrypt(data)
return result
},
/* 加密 */
encrypt(data) {
const PUBLIC_KEY = publicKey
var encryptor = new Encrypt()
encryptor.setPublicKey(PUBLIC_KEY)
// 如果是对象/数组的话,需要先JSON.stringify转换成字符串
const result = encryptor.encryptLong(data)
return result
},
/* 解密 - PRIVATE_KEY - 验证 */
decrypt(data) {
const PRIVATE_KEY = privateKey
var encryptor = new Encrypt()
encryptor.setPrivateKey(PRIVATE_KEY)
// 如果是对象/数组的话,需要先JSON.stringify转换成字符串
var result = encryptor.decryptLong(data)
return result
}
}
以上是加解密的方法,axios请求中的逻辑根据项目的后台需求更改