admin管理员组文章数量:1653285
前端
第一步:
//安装
npm install crypto-js --save-dev
第二步:
在src目录下新建个放公用js文件夹(common),再建一个AES.js文件(存放加密解密方法的工具文件),在AES.js中填写如下代码 :
import CryptoJS from 'crypto-js'
import { ENCRYPT_KEY, ENCRYPT_IV } from '@/BaseEnvConfig.js'
// ENCRYPT_KEY, ENCRYPT_IV 是在BaseEnvConfig.js文件里自定义的 密钥 (AES使用16位)
// let ENCRYPT_KEY = 'eW9ueW91OmFtbWE='
// let ENCRYPT_IV = 'abcdefghijklmn12'
let key = CryptoJS.enc.Utf8.parse(ENCRYPT_KEY)
let iv = CryptoJS.enc.Utf8.parse(ENCRYPT_IV)
// 加密函數
export function EncryptData (data) {
var srcs = CryptoJS.enc.Utf8.parse(data)
var encrypted = CryptoJS.AES.encrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
return encrypted.toString()
}
export function DecryptData (data) {
// var stime = new Date().getTime()
var decrypt = CryptoJS.AES.decrypt(data, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
var result = JSON.parse(CryptoJS.enc.Utf8.stringify(decrypt).toString())
// var etime = new Date().getTime()
// console.log('DecryptData Time:' + (etime - stime))
return result
}
第三步:
在需要的地方引入,然后调用,我这里是在axios请求前加密,获得响应数据后解密:
import axios from 'axios'
import { Toast } from 'vant'
import { VUE_APP_API, NODE_ENV } from '@/BaseEnvConfig.js'
import store from '@/store'
import { EncryptData, DecryptData } from '@/utils/encryUtil' // 引入加密解密方法的文件
axios.defaults.timeout = 30000
axios.defaults.baseURL = VUE_APP_API // 发布版本build时放开
/* 设置通用的请求和返回拦截 */
axios.interceptors.request.use(
config => {
if (store.getters.token) {
config.headers['token'] = store.getters.token
}
// do something before request is sent
// 约定 非开发模式,且是POST请求,并且是JSON数据格式的都启用参数加密,表单形式不启用参数加密
// if (config.method === 'post' && config.headers['Content-Type'] === jsonHeaders['Content-Type']) {
if (config.method === 'post' && NODE_ENV !== 'development' && config.headers['Content-Type'] === jsonHeaders['Content-Type']) {
// 这里的 if 是判断在什么情况下需要用到加密,一般在本机调试时是不需要加密,方便看数据变化,但如果发布部署到真机正常投入使用后,就需要进行加密了
config.data = EncryptData(JSON.stringify(config.data))
}
return config
},
error => {
errorMessage(error)
return Promise.reject(error)
}
)
axios.interceptors.response.use(
response => {
// 后端返回字符串表示需要解密操作,并且当前非开发环境下
// if (typeof (response.data) === 'string') {
if (typeof (response.data) === 'string' && NODE_ENV !== 'development') {
response.data = DecryptData(response.data)
}
const ret = response.data
console.log(ret)
if (ret.code === 401) {
store.dispatch('user/clearToken', '')
window.location.reload()
}
// 业务级异常
if (ret && ret.code && ret.code !== 0) {
// 参数异常,业务约束
errorMessage(ret.msg)
return Promise.reject(ret)
}
return ret
},
error => {
if (error.isAxiosError) {
errorMessage(error.message)
} else {
const ret = error.response
if (ret.dat) {
const msg = ret.data.msg || ret.data.message
errorMessage(msg)
}
}
return Promise.reject(error)
}
)
function errorMessage (msg) {
Toast.fail({
message: msg,
duration: 1.5 * 1000
})
}
const jsonHeaders = { 'Content-Type': 'application/json' }
// const jsonHeaders = { 'Content-Type': 'multipart/form-data' }
const formHeaders = { 'Content-Type': 'application/x-www-form-urlencoded' }
export default {
post (opts) {
return axios({
method: 'post',
url: opts.url || '',
data: opts.data,
// data: opts.toJson ? opts.data : qs.stringify(opts.data),
// params: opts.params || '',
// headers: opts.toJson ? jsonHeaders : formHeaders
headers: jsonHeaders
})
},
postFormData (opts) {
return axios({
method: 'post',
url: opts.url || '',
data: opts.data,
// data: opts.toJson ? opts.data : qs.stringify(opts.data),
// params: opts.params || '',
// headers: opts.toJson ? jsonHeaders : formHeaders
headers: formHeaders
})
},
get (opts) {
return axios({
method: 'get',
url: opts.url || '',
params: opts.params || ''
})
}
}
后端
编写加密工具类
/**
* AES 128bit 加密解密工具类
* @author dufy
*/
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AesEncryptUtil {
//使用AES-128-CBC加密模式,key需要为16位,key和iv可以相同!
private static String KEY = "eW9ueW91OmFtbWE=";
private static String IV = "abcdefghijklmn12";
/**
* 加密方法
* @param data 要加密的数据
* @param key 加密key
* @param iv 加密iv
* @return 加密的结果
* @throws Exception
*/
public static String encrypt(String data, String key, String iv) throws Exception {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");//"算法/模式/补码方式"NoPadding PkcsPadding
int blockSize = cipher.getBlockSize();
byte[] dataBytes = data.getBytes();
int plaintextLength = dataBytes.length;
if (plaintextLength % blockSize != 0) {
plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
}
byte[] plaintext = new byte[plaintextLength];
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(plaintext);
return new Base64().encodeToString(encrypted);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 解密方法
* @param data 要解密的数据
* @param key 解密key
* @param iv 解密iv
* @return 解密的结果
* @throws Exception
*/
public static String desEncrypt(String data, String key, String iv) throws Exception {
try {
byte[] encrypted1 = new Base64().decode(data);
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original);
return originalString;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 使用默认的key和iv加密
* @param data
* @return
* @throws Exception
*/
public static String encrypt(String data) throws Exception {
return encrypt(data, KEY, IV);
}
/**
* 使用默认的key和iv解密
* @param data
* @return
* @throws Exception
*/
public static String desEncrypt(String data) throws Exception {
return desEncrypt(data, KEY, IV);
}
/**
* 测试
*/
public static void main(String args[]) throws Exception {
String test1 = "sa";
String test =new String(test1.getBytes(),"UTF-8");
String data = null;
String key = KEY;
String iv = IV;
// /g2wzfqvMOeazgtsUVbq1kmJawROa6mcRAzwG1/GeJ4=
data = encrypt(test, key, iv);
System.out.println("数据:"+test);
System.out.println("加密:"+data);
String jiemi =desEncrypt(data, key, iv).trim();
System.out.println("解密:"+jiemi);
}
}
注意:秘钥需前后端保持一致
版权声明:本文标题:前后端请求参数加密 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dianzi/1729640233a1208528.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论