现在网站开发很多都用到前后端分离,保证API调用时数据的安全性便成了当务之急。
本文提供使用RAS非对称加密的方式传输数据。
1.保证API调用时数据的安全性的几种方式
- 使用HTTPS
- 使用数字签名确认,防止数据被篡改
- 身份确认机制,每次请求都要验证是否合法
- 对所有请求和响应的数据都进行加解密操作
2.加密思路介绍
本文着重对第4点进行介绍:对所有请求和响应的数据都进行加解密操作
由上图可知,数据在网络上传输时,都是使用密文传输,即使被抓包,没有私钥也没办法获取到原始数据。对于用户和业务逻辑而言,加解密过程则是透明的。
3.前端加密封装
3.1.生成公钥、私钥
可以使用在线工具进行生成: 在线生成非对称加密公钥私钥对
也可以使用 openssl
进行生成
建议生成两套密钥对,服务器一套,前端一套
建议生成两套密钥对,服务器一套,前端一套
建议生成两套密钥对,服务器一套,前端一套
注意:密钥长度: 1024 bit
密钥格式:PKCS#8
3.2.创建加解密工具类
需要安装jsencrypt
npm i jsencrypt -S
/*** RSAUtil.js ***/
import JSEncrypt from 'jsencrypt'
/*** 换成你自己的生成的公钥(PUBLIC KEY) ***/
const publicKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD9WVA/IMOrCb4SnO6zPuMfmQhM
KVSOL+N095MLLSG3f22MqasH1ZHSeAiaO92JRzdvufl0zAbhcZnUD2rmITryalwb
hSC2NnwaGcIujIONdFf11Gw31JIHHhMlbDK43tJdkdRY79I9KDF8m3tmkkOvqCJJ
4wjeEktuSs+sUwM9CQIDAQAB
-----END PUBLIC KEY-----`
/*** 换成你自己的生成的私钥(PRIVATE KEY) ***/
const privateKey = `-----BEGIN PRIVATE KEY-----
MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAP1ZUD8gw6sJvhKc
7rM+4x+ZCEwpVI4v43T3kwstIbd/bYypqwfVkdJ4CJo73YlHN2+5+XTMBuFxmdQP
auYhOvJqXBuFILY2fBoZwi6Mg410V/XUbDfUkgceEyVsMrje0l2R1Fjv0j0oMXyb
e2aSQ6+oIknjCN4SS25Kz6xTAz0JAgMBAAECgYEAu1lgzk4cZE9AD+OdYVAQBT3V
tPybWspvGgA67PjjBh9lk6+kmpaEz2+UbPn4SZwwkp6kqop2TCEF8Ju2IZhRTZpQ
wIcox+ZSQwXPiKAXtZi6L4P8DwNfr/l5e/EBPlMlwUlfavm0WFS/z/CcilrjbHqw
lVZOWC85JX4+ucTP2AECQQD+/86oySkhuerh9YaBe4fqnk/dPGuQFmIFeHSbSVCD
2T35sfXUxoSnX1KRAG4P4Y0D1ZvpEYbrXK3hDkygDa15AkEA/lfZHbVehG96ZRYx
oz5V6SUxrkXBnxdkDf1gjf1bZrMJM7ml/pE+67Dsrgm+1HXfi7iFtdOZFnHlZGiW
3pp4EQJBAIEiwOB/RuI6ifW2ZlCKY5FwbNeIMpy8iRVmI/9ECI9M4/LgqbMAectd
Ha4q/pHyUnx/n75PTvlAbRoNKMbhRlkCQQDfpyYfjqYPdOu+yjZZ4u2ut2spYOOy
3uG3v4/RK/HcrCCyYFSMNvKKVKi7HYy1zPUHKvpA+lGKwBrEIYhRNKnRAkEAmEDq
YrEL6DZeCLNHgYT9GZ3t87+dOGmonEjDBRrj4Z0HUok3tVV+0y3bKLkLr6fniqKh
mHTUs4tjYPRAhEkBzg==
-----END PRIVATE KEY-----`
const crypt = new JSEncrypt()
crypt.setPublicKey(publicKey)
crypt.setPrivateKey(privateKey)
function encrypt(data) {
const res = crypt.encrypt(JSON.stringify(data))
// 字符+和/分别替换成点 . 和下划线 _
return res.replace(/\+/g, '.').replace(/\//g, '_')
}
function decrypt(encryptData) {
// 将上面替换的规则还原
encryptData = encryptData.replace(/\./g, '+').replace(/_/g, '/')
return JSON.parse(crypt.decrypt(encryptData))
}
export default {encrypt, decrypt}
3.3.基于Axios封装request
需要安装axios
npm i axios -S
/*** requrst.js ***/
import axios from 'axios'
import RSAUtil from './RSAUtil'
// 创建axios实例
const service = axios.create({
baseURL: 'YOUR_BASE_URL', // url = base url + request url
timeout: 5000
})
// 请求拦截器,用来加密请求数据
service.interceptors.request.use(
config => {
if (typeof config.data !== 'undefined') {
config.data = {
data: RSAUtil.encrypt(JSON.stringify(config.data))
}
}
if (typeof config.params !== 'undefined') {
config.params = {
params: RSAUtil.encrypt(JSON.stringify(config.params))
}
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
// 响应拦截器,用来解密服务端的数据
service.interceptors.response.use(
response => {
// 解密后再返回
response['rawData'] = response.data
response['data'] = JSON.parse(RSAUtil.decrypt(response.data))
if (response.rawData !== null && response.data === null) {
return Promise.reject("私钥错误,解密失败")
}
return response
},
error => {
console.log('err' + error)
return Promise.reject(error)
}
)
export default service
4.测试
测试数据:
原始数据:`{name: "zhangsan"}`
密文:`X3IhyCFhwdO5aA8TvZfgct8jKX_HE21gEy.ZBpJtvYPWKq2bGxtjs.LxQ8Usa.KJi9oo209zgv8p8qDRVmWR5tZZeTxvAp7qR_miGE.Wtx9rkEBU9TMmeK5mOcgIDtbz8Uc9qwnYLY4fWWhUhDNfzIeMuatImtAHVYhHTssss1M=`
4.1.GET请求测试
import service from "../utils/request";
const res = await service.request({
url: 'https://getman.cn/mock/hsmus-top-ras-mock',
method: 'GET',
params: {
name: 'zhangsan'
}
})
console.log(res)
4.1.POST请求测试
import service from "../utils/request";
const res = await service.request({
url: 'https://getman.cn/mock/hsmus-top-ras-mock',
method: 'POST',
params: {
name: 'zhangsan'
}
})
console.log(res)
扫码在手机查看
您没有登录或者此篇文章不允许评论哟~~
暂无评论