yarn add crypto-es jsencrypt
CryptoES.mode:ECB
、CBC
(需要多加一个偏移量iv)
import CryptoES from 'crypto-es';
import JSEncrypt from 'jsencrypt';
注: 引入后报错
Can't resolve './JSEncrypt'
解决方法:
// webpack配置 module.rules添加
{
test: /\.m?js/,
resolve: {
fullySpecified: false
}
}
config-overrides.js
修改webpack配置const path = require('path');
const { override, addWebpackModuleRule } = require('customize-cra');
module.exports = override(
addWebpackModuleRule(
{
test: /\.m?js/,
resolve: {
fullySpecified: false
}
}
),
)
前后端用公钥加密
,AES 解密
加密
REACT_APP_SSOPUBLICKEY
公钥// 与后端约定共同使用公钥加密
const encryptor = new JSEncrypt();
encryptor.setPublicKey(process.env.REACT_APP_SSOPUBLICKEY ?? '');
// 随机数的方法
const aesKey = CryptoES.lib.WordArray.random(128 / 8).toString()
const aesIv = CryptoES.lib.WordArray.random(64 / 8).toString()
// 与后端约定前16位作为iv偏移量
const aesKeyVaue = encryptor.encrypt(aesIv + aesKey) || ''
.env文件
REACT_APP_SSOPUBLICKEY=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4ZPpIWdiMDcj8ELgtvPlxaEpKw7iHrqDhHrx92QMil1ZO/XvCJK1R1G4Tp5YV8hX9mp0qac8I+LNJ82zZMBpTdXEUlmlqtCuRMq9u1UcYN+hAlf6UL1LhKRXlEx5+EXBc4sgjUJUg8uYSqwIA8AfmbVU7bwODfwsxwFM2JVHbuwIDAQAB
解密
api.loginGetAccessInfo({
key: aesKeyVaue,
token: encryptor.encrypt(token ?? '') || ''
}).then((res: Respobject, { isOk }) => {
if (isOk) {
const decrypt = CryptoES.AES.decrypt(res.data, CryptoES.enc.Utf8.parse(aesKey),
{
iv: CryptoES.enc.Utf8.parse(aesIv),
mode: CryptoES.mode.CBC,
padding: CryptoES.pad.Pkcs7
});
// 获取解密后的data对象
const data = JSON.parse(CryptoES.enc.Utf8.stringify(decrypt).toString());
this.onUserInfoLoaded(data)
// 存储 key iv
localStorage.setItem('jst-aesKey', aesKey)
localStorage.setItem('jst-aesIv', aesIv)
} else {
localStorage.clear()
this.setState({ oauthSuccess: false })
}
}).catch(() => {
localStorage.clear()
this.initUserInfo()
})
aesKey
加解密request
加密、对返回的response
解密拦截器中统一加解密
this.axiosInstance
.request({
url: path,
method: req.method as any,
data: this.handleRequest(path, req),
headers: jstToken ? { ...headers, token: jstToken } : headers,
responseType: 'json'
})
handleRequest = (path: string, req: SwaRequest<RequestOptions>) => {
if (path.indexOf('/login/getAccessInfo') !== -1) {
return req.body || {}
}
console.log('req==', req)
console.log('enReq==', encrypt(req.body))
return encrypt(req.body)
}
用存储的key iv加密加密
function encrypt(params: any) {
const aesKey = localStorage.getItem('jst-aesKey') ?? ''
const aesIv = localStorage.getItem('jst-aesIv') ?? ''
const requestData = CryptoES.AES.encrypt(
JSON.stringify(params),
CryptoES.enc.Utf8.parse(aesKey),
{
iv: CryptoES.enc.Utf8.parse(aesIv),
mode: CryptoES.mode.CBC,
padding: CryptoES.pad.Pkcs7,
}
).toString();
return { requestData };
}
用存储的key iv加密解密
function decrypt(response: string) {
console.log('加密res==', response)
const aesKey = localStorage.getItem('jst-aesKey') ?? ''
const aesIv = localStorage.getItem('jst-aesIv') ?? ''
let data: string = ''
const result = CryptoES.AES.decrypt(
response,
CryptoES.enc.Utf8.parse(aesKey),
{
iv: CryptoES.enc.Utf8.parse(aesIv),
mode: CryptoES.mode.CBC,
padding: CryptoES.pad.Pkcs7,
}
).toString(CryptoES.enc.Utf8);
for (let i = 0; i < result.length; i++) {
if (result.charCodeAt(i) !== 0) {
data += `${result[i]}`
}
}
console.log('解密res==', JSON.parse(data))
return JSON.parse(data);
}