这里写目录标题
- controller
- 加解密工具类
- 加密(本质是对@ResponseBody加密)
- 解密(本质是对@RequestBody传参解密)
- 注解
controller
@Controller
public class PathVariableController {@GetMapping(value = "/test")@ResponseBodypublic HashMap<String, Object> test() {HashMap<String, Object> map = new HashMap<>();map.put("data","successqqqqqq");map.put("code",200);map.put("msg","成功");return map ;}@PostMapping(value = "/us")@ResponseBodypublic HashMap<String, Object> us(@RequestBody User user) {System.out.println(user.getAge()+user.getName());HashMap<String, Object> map = new HashMap<>();map.put("data",user.getName());map.put("code",200);map.put("msg",user.getAge());// map.put("name","lidapao里大炮");
// map.put("age",18);return map ;}
}
加解密工具类
package org.example.demo.demos.web;import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.io.*;
import java.security.Key;
import java.util.Base64;public class DESUtil {/*** 偏移变量,固定占8位字节*/private final static String IV_PARAMETER = "12345678";/*** 密钥算法*/private static final String ALGORITHM = "DES";/*** 加密/解密算法-工作模式-填充模式*/private static final String CIPHER_ALGORITHM = "DES/CBC/PKCS5Padding";/*** 默认编码*/private static final String CHARSET = "utf-8";/*** 生成key** @param password* @return* @throws Exception*/private static Key generateKey(String password) throws Exception {DESKeySpec dks = new DESKeySpec(password.getBytes(CHARSET));SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);return keyFactory.generateSecret(dks);}/*** DES加密字符串** @param password 加密密码,长度不能够小于8位* @param data 待加密字符串* @return 加密后内容*/public static String encrypt(String password, String data) {if (password== null || password.length() < 8) {throw new RuntimeException("加密失败,key不能小于8位");}if (data == null)return null;try {Key secretKey = generateKey(password);Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);byte[] bytes = cipher.doFinal(data.getBytes(CHARSET));//JDK1.8及以上可直接使用Base64,JDK1.7及以下可以使用BASE64Encoder//Android平台可以使用android.util.Base64return new String(Base64.getEncoder().encode(bytes));} catch (Exception e) {e.printStackTrace();return data;}}/*** DES解密字符串** @param password 解密密码,长度不能够小于8位* @param data 待解密字符串* @return 解密后内容*/public static String decrypt(String password, String data) {if (password== null || password.length() < 8) {throw new RuntimeException("加密失败,key不能小于8位");}if (data == null)return null;try {Key secretKey = generateKey(password);Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);return new String(cipher.doFinal(Base64.getDecoder().decode(data.getBytes(CHARSET))), CHARSET);} catch (Exception e) {e.printStackTrace();return data;}}/*** DES加密文件** @param srcFile 待加密的文件* @param destFile 加密后存放的文件路径* @return 加密后的文件路径*/public static String encryptFile(String password, String srcFile, String destFile) {if (password== null || password.length() < 8) {throw new RuntimeException("加密失败,key不能小于8位");}try {IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, generateKey(password), iv);InputStream is = new FileInputStream(srcFile);OutputStream out = new FileOutputStream(destFile);CipherInputStream cis = new CipherInputStream(is, cipher);byte[] buffer = new byte[1024];int r;while ((r = cis.read(buffer)) > 0) {out.write(buffer, 0, r);}cis.close();is.close();out.close();return destFile;} catch (Exception ex) {ex.printStackTrace();}return null;}/*** DES解密文件** @param srcFile 已加密的文件* @param destFile 解密后存放的文件路径* @return 解密后的文件路径*/public static String decryptFile(String password, String srcFile, String destFile) {if (password== null || password.length() < 8) {throw new RuntimeException("加密失败,key不能小于8位");}try {File file = new File(destFile);if (!file.exists()) {file.getParentFile().mkdirs();file.createNewFile();}IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, generateKey(password), iv);InputStream is = new FileInputStream(srcFile);OutputStream out = new FileOutputStream(destFile);CipherOutputStream cos = new CipherOutputStream(out, cipher);byte[] buffer = new byte[1024];int r;while ((r = is.read(buffer)) >= 0) {cos.write(buffer, 0, r);}cos.close();is.close();out.close();return destFile;} catch (Exception ex) {ex.printStackTrace();}return null;}public static void main(String[] args) {String key = "98fbffd1064a4355b8abaacb6fa96f94";String data="bDyb3N+87Imt+LmOEklv+ttCM2Z/5pHnYbJKbQ41bvozUKMMSrScP/xhHCYUJBrKI/aIDaDs7BE=";//String data="Khrcd+W7L/+PkWYPB/2qrgL7G8agzQXJ2xWdU8q67sfpjBd+C9nwEFdqDiBpbtTGP8jjcUJnOYILEMPtbKH+6YiqhMcluTRlkoXrPePhfQFOa/69mrwXn42jZsx1g1mR7AqOwdoGoz2rIQRh5RAn3uFuaN9nonQ2sFhxb9f+YA/5umlWVc8v37t4RmrFv4PO0xlqNV4lkXgdj2AnvUqxfBIizKXRgxFdvyqwydiXEL2+sMMc1B/mJY1C8N1pK92St/rF9Bj94fZdewHL3pQklxfl3c1bVqXexIY/CjCrSwmhkTdKMWWC4+81Z9kPlNUDnas3b2Wi/OgoHJVuQIhXShu+KSqBSxWPkECNo6OX/L5zUUa45NOIUOqXVduZhxlvm1/CvzgqLUPlEaAWfIZWzw==";
// System.out.println("加密前key:" + key);
// System.out.println("加密前data:" + key);
// String rc="{\"corpKey\":\"913205080884374764\"}";
// String en = encrypt(key,rc);
// System.out.println("加密后:" + en);String de = decrypt(key,data);System.out.println("解密后:" + de);}
}
加密(本质是对@ResponseBody加密)
package com.ruoyi.framework.config;import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.annotation.Encrypt;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.DESUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;import java.util.HashMap;
import java.util.Map;/*** 加解密接口处理*/
@RestControllerAdvice
public class EncodeAdvice implements ResponseBodyAdvice {private Logger log = LoggerFactory.getLogger(EncodeAdvice.class);@Overridepublic boolean supports(MethodParameter methodParameter, Class aClass) {return true;}@Nullable@Overridepublic Object beforeBodyWrite(@Nullable Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {boolean encode = true;// 出参 配置文件控制 默认打开String isEncrypt = RuoYiConfig.getIsEncrypt();if ("true".equals(isEncrypt)) {if (methodParameter.getMethod().isAnnotationPresent(Encrypt.class)) {Encrypt serializedField = methodParameter.getMethodAnnotation(Encrypt.class);encode = serializedField.encode();}if (encode) {log.info("对方法method :【" + methodParameter.getMethod().getName() + "】返回数据进行加密");String secretPrivateKey = RuoYiConfig.getPrivateKey();ObjectMapper objectMapper = new ObjectMapper();try {String result = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(body);Map<String, String> data = new HashMap<>();String enData = DESUtil.encrypt("98fbffd1064a4355b8abaacb6fa96f94", result);// String enData2 = RsaUtils.encryptByPublicKey(RuoYiConfig.getPublicKey(), result);data.put("data", enData);// String s3 = RsaUtils.decrypt(RuoYiConfig.getPrivateKey(), enData);return data;} catch (Exception e) {e.printStackTrace();log.error("对方法method :【" + methodParameter.getMethod().getName() + "】返回数据进行加密出现异常:" + e.getMessage());}}}return body;}
}
解密(本质是对@RequestBody传参解密)
package com.ruoyi.framework.config;import cn.hutool.core.exceptions.ExceptionUtil;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.annotation.Encrypt;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.DESUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;import java.io.InputStream;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.Map;@Slf4j
@RestControllerAdvice
public class DecodeAdvice implements RequestBodyAdvice {@Overridepublic boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {return true;}@Overridepublic HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter,Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {try {// 入参默认加密boolean isDecode = true;if (parameter.getMethod().isAnnotationPresent(Encrypt.class)) {Encrypt encrypt = parameter.getMethodAnnotation(Encrypt.class);isDecode = encrypt.decode();}if (isDecode) {log.info("对方法method :【" + parameter.getMethod().getName() + "】入参进行解密");if (inputMessage.getHeaders().containsKey("requestType")) {String requestType = inputMessage.getHeaders().get("requestType").get(0);if (requestType.equals("post")) {return new MyHttpInputMessage(inputMessage, requestType);} else if (requestType.equals("put")) {return new MyHttpInputMessage(inputMessage, requestType);// return inputMessage;} else {return inputMessage;}} else {return inputMessage;}} else {return inputMessage;}} catch (Exception e) {log.error("对方法method :【" + parameter.getMethod().getName() + "】入参解密失败");log.error(ExceptionUtil.getMessage(e));return inputMessage;}}@Overridepublic Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter,Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {return body;}@Overridepublic Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter,Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {return body;}class MyHttpInputMessage implements HttpInputMessage {private HttpHeaders headers;private InputStream body;/*** inputMessage 解密后重新赋值** @param inputMessage* @param requestType* @throws Exception*/public MyHttpInputMessage(HttpInputMessage inputMessage, String requestType) throws Exception {this.headers = inputMessage.getHeaders();if (requestType.equals("put")) {InputStream inputStream = inputMessage.getBody();String body = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);this.body = IOUtils.toInputStream(easpString(body), "utf-8");} else {this.body = IOUtils.toInputStream(easpString(IOUtils.toString(inputMessage.getBody(), "utf-8")), "utf-8");}}@Overridepublic InputStream getBody() {return body;}@Overridepublic HttpHeaders getHeaders() {return headers;}/*** @param requestData* @return*/public String easpString(String requestData) {if (requestData != null && !"".equals(requestData)) {Map<String, String> map = JSONObject.parseObject(requestData, Map.class);// 密文String isEncrypt = RuoYiConfig.getIsEncrypt();if (isEncrypt.equals("false")) {return requestData;}String data = map.get("dataBody");if (StringUtils.isEmpty(data)) {throw new RuntimeException("参数【requestData】缺失异常!");} else {String content;try {content = DESUtil.decrypt("98fbffd1064a4355b8abaacb6fa96f94", data);} catch (Exception e) {throw new RuntimeException("参数解析异常!");}return content;}}throw new RuntimeException("参数【requestData】不合法异常!");}}
}
注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Encrypt {/*** 接收参数是否解密 默认true* @param*/boolean decode() default true;/*** 返回体是否加密 默认true* @return*/boolean encode() default true;}
== 加解密的配置从yaml配置文件里读 ==