这里写目录标题
- controller
- 加解密工具类
- 加密(本质是对@ResponseBody加密)
- 解密(本质是对@RequestBody传参解密)
- 注解
controller
@Controller
public class PathVariableController {
@GetMapping(value = "/test")
@ResponseBody
public 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")
@ResponseBody
public 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.Base64
return 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);
@Override
public boolean supports(MethodParameter methodParameter, Class aClass) {
return true;
}
@Nullable
@Override
public 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 {
@Override
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public 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;
}
}
@Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter,
Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return body;
}
@Override
public 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");
}
}
@Override
public InputStream getBody() {
return body;
}
@Override
public 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配置文件里读 ==