这里不做过多解释AES加解密是什么,直接上代码

  1. 首先导入crypto-js文件
  2. 写一个aes.js加解密的工具类
import CryptoJS from '...crypto-js'
//密钥 16位
const key = '1111122222333334'
//偏移量 16位
const iv = '0000000000000000'

//加密 ECB模式 不需要iv(偏移量)
function Enctry(word){
	return CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(word),CryptoJS.enc.Utf8.parse(key),{
		iv:CryptoJS.enc.Utf8.parse(iv),
		mode:CryptoJS.mode.ECB,
		padding:CryptoJS.pad.Pkcs7
	})
	.toString()
}

//解密 ECB模式 不需要iv(偏移量)

function Decrypt(word){
	let decrypted = CryptoJS.AES.decrypt(word,CryptoJS.enc.Utf8.parse(key),{
		mode:CryptoJS.mode.ECB,
		padding:CryptoJS.pad.Pkcs7
	})
	return decrypted.toString(CryptoJS.enc.Utf8).toString()
}

export default{
	Encrypt,
	Decrypt
}
  1. 在request.js文件中对数据进行加密
//加密开关

import AES from './aes.js'
import CryptoJs from '...crypto-js'

const startAes = true;

service interceptors.request.use(
	config => {
			
		if(config.method == 'get'){

			//AES加密
			if( (config.url.startsWith('开头是否包含请求地址') || (config.url.startsWith('开头是否包含请求地址') ) && startAes == true ){
				for(var key in config.params){
					config.params[key] = CryptoJS.enc.stringify(CryptoJS.enc.utf8.parse(AES.Encrypt(config.params[key])))
				}
				//md5签名
				config.headers['md5'] = CryptoJS.MD5(JSON.stringifg(config.params)).toString()
				//加密标志
				config.headers['aes-encrypt'] = 'true'
			}	
			
		}else if (config.method == 'post'){
			
			config.transformRequest = function(data){
				
				//导出时添加请求头exportFlag:true,这个地方忽略导出,加密导致导出失败
				if( (config.url.startsWith('开头是否包含请求地址') || (config.url.startsWith('开头是否包含请求地址') ) && startAes == true && config.headers.exportFlag != true ){
					
					
					//md5签名
					config.headers['md5'] = CryptoJS.MD5(data).toString()
					//加密标志
					config.headers['aes-encrypt'] = 'true'
					//data机密 --这里对参数单个加密,如果对整个body加密后台不容易处理
					let da = {}
					let dataa = data.split('&')
					let ea = []
					dataa.forEach(function(element,i){
						ea = element.split('=')
						da[ea[0]] = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(AES.Encrypt(ea[1])))
					})

					ea = []
					for(var key in da){
						ea.push(key+'='+da[key])
					} 
					data = ea.join('&')
				}
				//
				return data
			}
		}
		return config
	},
	error => {
		return Promise.reject(error)
	}
)
  1. 后端数据传输加解密工具类
public class AesEncryptUtils {
	//密钥 前后台一致16位
	private static final String KEY = "1111122222333334";
	//参数分别代表 算法名称/加密模式/数据填充方式
	private static final String ALGORITHMESTR = "AES/ECB/PKCS5Padding";

	//加密
	public static String encrypt(String content,String encryptKey)throws Exception{
		KeyGenerator kgen = KeyGenerator.getInstance("AES");
		kgen.init(128);
		Cipher cipher = Cipher.getInstance(ALGORITHMESTR);
		cipher.init(Cipher.ENCRYPT_MODE,new SecretKeySpec(encryptkey.getBytes(),"AES"));
		byte[] b = cipher.doFinal(content.getBytes("utf-8"));
		//采用base64算法进行转码,避免出现中文乱码
		return Base64.encodeBaseString(b);
	}

	//解密
	public static String decrypt(String encryptStr,String decryptKey)throws Exception{
		KeyGenerator kgen = KeyGenerator.getInstance("AES");
		kgen.init(128);
		Cipher cipher = Cipher.getInstance(ALGORITHMESTR);
		cipher.init(Cipher.DECRYPT_MODE,new SecretKeySpec(decryptKey.getBytes(),"AES"));
		byte[] b = cipher.doFinal(Base64.decodeBase64(encryptStr));
		//采用base64算法进行转码,避免出现中文乱码
		return new String(b);
	}
}
  1. 配置过滤器启动
@Configuration
public class FilterConfig{

	@Bean
	public FilterRegistrationBean filterRegistrationBean (){
		FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean ();
		filterRegistrationBean.setOrder(1);
		filterRegistrationBean.setFilter(new AesFilter());
		filterRegistrationBean.setName("AesFilter");
		filterRegistrationBean.addUrlPatterns("/*");
		return filterRegistrationBean;
	}
}
  1. 异常处理类
public class ExceptionCommonUtils{
	pulbic static String getId(){
		return uuid.replace("-","");
	}
	//用来响应信息
	public static void responseMessage(HttpServletResponse response,Integer code,String message)throw IOException{
		Map<String,Object> map = new HashMap<>();
		map.put("code",code);
		map.put("message",message);
		response.setContentType(text/json;charset=utf-8);
		JSONObject fromObject = JSONObject.formObject(map);
		PrintWriter pw = response.getWriter();
		pw.write(fromObject.toString());
		pw.flush();
		pw.close();
		
	}
}
  1. 写一个过滤器进行aes解密
public class AesFilter implements Filter{
	//初始化方法和销毁方法在此省略

	@Override
	public void doFilter(ServletRequest  request,ServletResponse response,FilterChain filterChain){
		try{
			HttpServletRequest hsr = (HttpServletRequest)request;
			Enumeration<String> headerNames = hsr.getHeaderNames();
			while(headerNames.hasMoreElements){
				String ele = headerNames.nextElements();
			}
			//前台是否加密的标记,请求数据是否已经加密
			if("true".equals(hsr.getHeader("aes-encrypt"))){
				//调用自定义request解析参数
				filterChain.doFilter(new AesFilterWrapper((HtppServletRequest)request),response);
			}else{
				filterChain.doFilter(request,response);
			}
		}catch(ManageException e){
			ExceptionCommonUtils.responseMessage((HtppServletResponse)response,e.getCode,e.getMessage());
		}catch(Exception e){
			ExceptionCommonUtils.responseMessage((HtppServletResponse)response,e.getCode,e.getMessage());
		}
	}
}
  1. 对所有参数进行aes解密
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class AesFilterWrapper extends HttpServletRequestWrapper {

	Logger log  = LoggerFactory.getLogger(this.getClass());

	public AesFilterWrapper (HttpServletRequest request) {
		super(request);
	}
	
	@Override
	public String[] getParameterValues(String s) {
		
		String str[] = super.getParameterValues(s);
		if (str == null) {
			return null;
		}
		int i = str.length;
		for (int j = 0; j < i; j++) {
			//System.out.println("getParameterValues:"+str[j]);
			str[j] = deCrypto(str[j]);
		}

		return str;
	}
	
	@Override
	public String getParameter(String s) {
		String s1 = super.getParameter(s);
	
		if (s1 == null) {
			return null;
		} else {
			return deCrypto(s1);
		}
	}
	
	@Override
	public Map<String,String[]> getParameterMap(){
		HashMap<String,String[]>   paramMap = (HashMap<String,String[]>)super.getParameterMap();
		paramMap = (HashMap<String,String[]>) paramMap.clone();
		for(Iterator iterator = (Iterator) paramMap.entrySet().iterator();iterator.hasNext();){
			Map.Entry<String, String[]> entry = (Map.Entry<String, String[]>) iterator.next();
			String[] values = entry.getValue();
			for(int i=0;i<values.length;i++){
				if(values[i]!=null){
					values[i] = deCrypto(values[i]);
				}
			}
			entry.setValue(values);
		}
		return paramMap;
	}
	
	//Aes解密
	public String deCrypto(String src){
		try{
		
			return URLDecoder.decode(AesEncryptUtils.decrypt(new String(Base64.getDecoder(src))),"UTF-8");
			
		}catch(Exception e){
			log.info(e.getMessage());
			return src
		}
	}

}
  1. 写一个date.properties来定义日期格式
app.date-format-string=yyyy-MM-dd
  1. 自定义aes加密注解
@Target(value={ElementType.PARAMETER,ElementType.METHOD})
@Retention(value = REtentionPolicy.RUNTIME)
@Documented
public @interface AesEncrypt{
	String name() default "name";
}
  1. 在所需要加密的Controller层方法上加上注解就可以 @AesEncrypt
  2. 后端对数据进行加密
@ControllerAdvice
@PropertySource("date.properties")
public class AesEncodeAdvice implements ResponseBodyAdvice{
	
	@Value("${app.date-format-string}")
	public String dateFormatString;
	
	public String getDateFormatString(){
		return dateFormatString;
	}
	
	public void setDateFormatString(String dateFormatString){
		this.dateFormatString = dateFormatString
	}
	
	//是否执行
	@Override
	public boolean supports(MethodParameter arg0,Class arg1){
		
		//查找带有@AesEncrypt注解的方法进行加密
		boolean isSupports = arg0.hasMethodAnnotation(AesEncrypt.class);
		return isSupports;
		//false 不进行加密
		//return false;
	}

	@Override
	public Object beforeBodyWrite(Object params,MethodParameter arg1,MediaType arg2,Class arg3,ServletHttpRequet shresq,ServletHttpResponse shresp){
		try{
			//是否是后台调用
			boolean serverRequest = false;
			
			HtppServletRequest servletRequest = ((HtppServletRequest) shresq.getServletRequest();
			Enumeration<String> headerNames = servletRequest.getHeaderNames();
			String key = null;
			String value = null;
			while(headerNames.hasMoreElements()){
				key = headerNames.nextElement();
				//根据这个请求头 进行不加密
				if("请求头key".equals(key)){
					serverRequest  = true;
				}
			}

			//因加密不会对Date进行处理,这里在加密前对Date进行处理
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(getDateFormatString());
			objectMapper.setDateFormat(simpleDateFormat); 

			String result = "";
			if(params instanceof String){
				result = (String)params;	
			}else{
				result = objectMapper.writerWithDefaultprettyPrinter().writeValueAsString(params);
			}
			//后台服务之间的调用,不需要加密
			//为了安全起见,这个判断方法不要告诉别人
			if(serverRequest){
				return params;
			}else{
				//添加响应头--用于前端解析加密数据
				HttpServletResponse serlvetResponse = ((ServletServerHttpResponse)shresp).getServletResponse();
				servletResponse.addHeader("aes-encrypt","true");
				//调用加密方法
				return AesEncryptUtils.encrypt(result);
			}

		}catch(Exception e){
			e.printStackTrace();
		}
		return params;
	}
}
  1. vue request.js文件中对数据进行解密
service.interceptors.response.use(

	response => {
		if( (config.url.startsWith('开头是否包含请求地址') || (config.url.startsWith('开头是否包含请求地址') ) && startAes == true && response.headers["aes-encrypt"]==true){

			//通过try catch 捕捉异常,防止代码报错
			try{
				response.data = JSON.parse(AES.Decrypt(response.data));
			}catch(d){
			
			}
		}
	}

)