目录
前言
一、前端工作准备
1.下载crypto-js
2.加密解密工具类
3.对axios请求拦截加密
二、后端工作准备
1.所需依赖
2.实现RequestBodyAdvice
3.实现HttpInputMessage
三、数据响应加密(扩展)
1.实现 ResponseBodyAdvice(后端)
2.axios响应拦截器(前端)
前言
在数字化时代,数据安全已成为企业和社会关注的焦点。为了确保数据的机密性和完整性,我们采用SpringBoot和Vue技术,结合AES对称加密,构建一个高效且安全的系统。AES加密算法以其高度的安全性和广泛的应用场景,成为了数据加密的首选方案。通过在SpringBoot后端实现AES加密和解密逻辑,我们能够确保数据在传输和存储过程中的安全。同时,在Vue前端,我们利用相应的加密和解密方法,实现了与后端的无缝对接。这样,无论是数据的发送还是接收,都能够得到充分的保护。这种加密方案不仅提高了系统的安全性,也增强了用户的信任度。
一、前端工作准备
1.下载crypto-js
npm install crypto-js --save-dev
2.加密解密工具类
keyOne是自己设置的一个key,可以根据你自己的业务来设置
import cryptoJs from 'crypto-js'
// 加密
let keyOne = '313233343536373a'
export function encrypt(word) {let key = cryptoJs.enc.Utf8.parse(keyOne)let enc = ''if (typeof word === 'string') {enc = cryptoJs.AES.encrypt(word, key, {// iv: ivmode: cryptoJs.mode.ECB,padding: cryptoJs.pad.Pkcs7})} else if (typeof word === 'object') {let data = JSON.stringify(word)enc = cryptoJs.AES.encrypt(data, key, {// iv: ivmode: cryptoJs.mode.ECB,padding: cryptoJs.pad.Pkcs7})}let encryptedData = enc.ciphertext;var encryptedBase64Str = encryptedData.toString().replace(/\//g, "_");encryptedBase64Str = encryptedBase64Str.replace(/\+/g,"-");console.log(encryptedBase64Str)return encryptedBase64Str;
}//解密
export function decrypt(word) {console.log('传入的密文:', word)let key = cryptoJs.enc.Hex.parse(keyOne)let dec = cryptoJs.AES.decrypt(cryptoJs.format.Hex.parse(word), key, {// vi: vimode: cryptoJs.mode.ECB,padding: cryptoJs.pad.Pkcs7})return cryptoJs.enc.Utf8.stringify(dec)
}
3.对axios请求拦截加密
这边我设置有一个拦截器,并且我只对Post请求进行拦截,其他请求不拦截,如果你想要其他请求(get、put、delete)进行拦截,则可以仿照Post请求来进行数据加密
const whiteList = ['/user/login',"/upload/oss"]; //排除的路径
// 请求拦截器
service.interceptors.request.use(config => {if (store.getters.token) {// 设置令牌请求头config.headers['authorization'] = store.getters.token;}if (config.method === 'post' && whiteList.indexOf(config.url)===-1 && config.data){config.headers['Content-Type'] = 'application/json;charset=UTF-8';config.data = encrypt(config.data)}return config},error => {return Promise.reject(error)}
);
二、后端工作准备
1.所需依赖
<!-- hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.17</version></dependency>
2.自定义注解
该注解用于在Post请求的方法上添加,open字段为是否打开解密,默认为true(打开)。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AESCrypto {boolean open() default true;
}
3.实现RequestBodyAdvice
package com.pzg.chat.handler;
@Slf4j
@ControllerAdvice
public class DecryptRequestBodyAdviceHandler implements RequestBodyAdvice {@Value("${crypto.charset}")private String charset = "UTF-8";@Value("${crypto.key}")private String key;@Overridepublic boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {return true;}@Overridepublic HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {AESCrypto methodAnnotation = methodParameter.getMethodAnnotation(AESCrypto.class);if (methodAnnotation!=null && BooleanUtil.isTrue(methodAnnotation.open())){return new DecryptHttpInputMessageHandler(inputMessage , charset , key);//请求信息解密,参考DecryptHttpInputMessage解密类}return inputMessage;}@Overridepublic Object afterBodyRead(Object body, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {return body;}@Overridepublic Object handleEmptyBody(Object body, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {return body;}
}
4.实现HttpInputMessage
public class DecryptHttpInputMessageHandler implements HttpInputMessage {private HttpInputMessage inputMessage;private String charset;private String key;public DecryptHttpInputMessageHandler(HttpInputMessage inputMessage, String charset , String key) {this.inputMessage = inputMessage;this.charset = charset;this.key = key;}@Overridepublic InputStream getBody() throws IOException {//使用hutool开始解密InputStream body = inputMessage.getBody();String content = IoUtil.read(body , charset);byte[] bytes = SecureUtil.aes(key.getBytes(charset)).decrypt(content);return new ByteArrayInputStream(bytes);}@Overridepublic HttpHeaders getHeaders() {return inputMessage.getHeaders();}
}
最后当前端发送post请求到后端后,就会被我们定义的 DecryptRequestBodyAdviceHandler 类所拦截,并获取其中信息并进行解密。
三、数据响应加密(扩展)
1.实现 ResponseBodyAdvice<Object>(后端)
@ControllerAdvice
public class EncryptResponseBodyAdviceHandler implements ResponseBodyAdvice<Object> {@Overridepublic boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {return true;}@Overridepublic Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {sout("-------------->你的加密逻辑")return null;}
}
2.axios响应拦截器(前端)
axios.interceptors.response.use((response) => {console.log("----------->解密逻辑")switch (response.data.code) {case 40001:Vue.prototype.$message({type: 'error',message: response.data.message})router.push({ path: '/login' })breakcase 50000:Vue.prototype.$message({type: 'error',message: response.data.message})break}return response},(error) => {return Promise.reject(error)}
)