Springboot请求参数解密
新建一个 HttpServletRequestWrapper 实现类,在Filter 中使用该类包装原request
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.net.URLDecoder;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.test.base.config.SecretConfig;
import com.test.common.constant.CommonConstant;
import com.test.common.exception.IchibanShoException;
import com.test.common.servlet.CommonServletInputStream;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.*;
@Slf4j
public class DecryptHttpServletRequest extends HttpServletRequestWrapper {
private byte[] body;
private static SecretConfig secretConfig;
private final Map<String, String[]> parameterMap = new HashMap<>();
public DecryptHttpServletRequest (HttpServletRequest request) {
super(request);
if (Objects.isNull(secretConfig)) {
secretConfig = SpringUtil.getBean(SecretConfig.class);
}
if (MapUtil.isNotEmpty(request.getParameterMap())) {
parameterMap.putAll(request.getParameterMap());
}
decryptSecretParam();
decryptPostBody(request);
}
private void decryptSecretParam() {
String secretParam = getParameter("secretParam");
MapUtil.removeAny(parameterMap, "secretParam");
if (StrUtil.isNotBlank(secretParam) && Objects.nonNull(secretConfig)) {
log.info(">>>>>>>>>>> 解密 secretParam 开始 <<<<<<<<<<<<<<<<<<");
log.info("原始secretParam: {}", secretParam);
secretParam = URLDecoder.decode(secretParam, StandardCharsets.UTF_8);
log.info("URLDecoder后secretParam: {}", secretParam);
String privateKey = secretConfig.getPrivateKey();
String publicKey = secretConfig.getPublicKey();
if (CharSequenceUtil.isNotBlank(privateKey)) {
RSA rsa = SecureUtil.rsa(privateKey, publicKey);
rsa.setDecryptBlockSize(CommonConstant.RSA_DECRYPT_BLOCK_SIZE);//hutool RSA解密默认128
String decryptData = rsa.decryptStr(secretParam, KeyType.PrivateKey);
log.info("RSA解码后secretParam: {}", decryptData);
decryptData = URLDecoder.decode(decryptData, StandardCharsets.UTF_8);
log.info("URLDecoder后decryptData: {}", decryptData);
if (CharSequenceUtil.isNotBlank(decryptData)) {
decryptData = StrUtil.removePrefix(decryptData, "\"");
decryptData = StrUtil.removeSuffix(decryptData, "\"");
log.info("去除首尾双引号后decryptData: {}", decryptData);
List<String> params = StrUtil.split(decryptData, "&");
for (String param : params) {
List<String> paramArr = StrUtil.splitTrim(param, "=");
if (CollUtil.isNotEmpty(paramArr) && paramArr.size() == 2) {
setParameter(paramArr.get(0), paramArr.get(1));
}
}
}
}
log.info(">>>>>>>>>>> 解密 secretParam 结束 <<<<<<<<<<<<<<<<<<");
}
}
private void decryptPostBody(HttpServletRequest request) {
try {
InputStream inputStream = request.getInputStream();
String bodyStr = IoUtil.read(new InputStreamReader(inputStream));
if (JSONUtil.isTypeJSON(bodyStr)) {
JSONObject jsonObject = JSONUtil.parseObj(bodyStr);
if (jsonObject.containsKey("secretData")) {
bodyStr = jsonObject.getStr("secretData");
}
}
if (!JSONUtil.isTypeJSON(bodyStr) && CharSequenceUtil.isNotBlank(bodyStr) && Objects.nonNull(secretConfig)) {
log.info(">>>>>>>>>>> 解密 secretData 开始 <<<<<<<<<<<<<<<<<<");
log.info("原始secretData: {}", bodyStr);
String privateKey = secretConfig.getPrivateKey();
String publicKey = secretConfig.getPublicKey();
if (CharSequenceUtil.isNotBlank(privateKey)) {
RSA rsa = SecureUtil.rsa(privateKey, publicKey);
rsa.setDecryptBlockSize(CommonConstant.RSA_DECRYPT_BLOCK_SIZE);
String decryptData = rsa.decryptStr(bodyStr, KeyType.PrivateKey);
log.info("RSA解码后secretData: {}", decryptData);
decryptData = URLDecoder.decode(decryptData, StandardCharsets.UTF_8);
log.info("URLDecoder后secretData: {}", decryptData);
if (CharSequenceUtil.isNotBlank(decryptData)) {
body = CharSequenceUtil.bytes(decryptData);
} else {
throw new IchibanShoException("无效的请求参数");
}
} else {
body = CharSequenceUtil.bytes(bodyStr);
}
log.info(">>>>>>>>>>> 解密 secretData 结束 <<<<<<<<<<<<<<<<<<");
} else {
body = CharSequenceUtil.bytes(bodyStr);
}
} catch (Exception e) {
log.error("解密失败", e);
}
}
public void setParameter(String name, String value) {
parameterMap.put(name, new String[] { value });
}
@Override
public String getParameter(String name) {
String[] values = parameterMap.get(name);
if (ArrayUtil.isNotEmpty(values)) {
return values[0];
}
return StrUtil.EMPTY;
}
@Override
public Map<String, String[]> getParameterMap() {
return parameterMap;
}
@Override
public Enumeration<String> getParameterNames() {
Vector<String> parameterNames = new Vector<>(parameterMap.keySet());
return parameterNames.elements();
}
@Override
public String[] getParameterValues(String name) {
return parameterMap.get(name);
}
@Override
public ServletRequest getRequest() {
return super.getRequest();
}
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(body)));
}
@Override
public ServletInputStream getInputStream() {
return new CommonServletInputStream(new ByteArrayInputStream(body));
}
}
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class CommonServletInputStream extends ServletInputStream {
private final ByteArrayInputStream inputStream;
public CommonServletInputStream(ByteArrayInputStream inputStream) {
this.inputStream = inputStream;
}
@Override
public boolean isFinished() {
return inputStream.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() {
return inputStream.read();
}
@Override
public void close() throws IOException {
inputStream.close();
}
}
在filter中:filterChain.doFilter(new DecryptHttpServletRequest(request), response);

浙公网安备 33010602011771号