RSA加密方法:基础RSA加密算法,包含分段加密及分段解密 分段加密过程: 第一步:完整信息base64加密 第二步:base64信息最大字节分组切割 第三步:切割后base64信息加密 第四步:RSA加密后信息再次base64加密 第五步:加密后base64字段拼接
分段解密过程:
第一步:完整base64字段分割
第二步:base64解密分割的字段
第三步:RSA解密
第四步:解密后数据进行拼接
第五步:拼接后数据进行base64解密
package com.xinjian.x.common.utils;
import com.alibaba.fastjson.JSONObject;
import org.springframework.util.Base64Utils;
import javax.crypto.Cipher;
import java.net.URLDecoder;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class RSAUtil {
public static final String KEY_ALGORITHM = "RSA";
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/**
* 公钥关键字
*/
private static final String PUBLIC = "RSAPublicKey";
/**
* 私钥关键字
*/
private static final String PRIVATE = "RSAPrivateKey";
public static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCWh3Nyt+5QqUXw1qHXM4k7lq98f9wA4iQgKK1LB1tr4uIgL/dls0LkBgY4oS/Dn3J0qHkpUTkTT84uMHey7cwdd9k90/65cpdawX0J0KO3S3Zwl9d5AJt7/hdSap3AcHw3dvlrZvvDJ72AaR3YUPujNM3dhLC7tsdDb3CxoJSBDQIDAQAB";
public static final String PRIVATE_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJaHc3K37lCpRfDWodcziTuWr3x/3ADiJCAorUsHW2vi4iAv92WzQuQGBjihL8OfcnSoeSlRORNPzi4wd7LtzB132T3T/rlyl1rBfQnQo7dLdnCX13kAm3v+F1JqncBwfDd2+Wtm+8MnvYBpHdhQ+6M0zd2EsLu2x0NvcLGglIENAgMBAAECgYAsR/ZXRfJOOi1/9rOvSdLR+7bt6fL/M4crCqxHyQdEyn54t4OQoFZKG9eSqyAQ7QPPe4wA8orWuoBNqCZeNYP4pXV2ayPwZcUSN9SX4/ce5QZkhHDVBwC8SIQQ7osU6Joh4gR3I+CHlmM1dCItBizOC0Jw4Scs7cpnzzMgYhdPoQJBAO9gzFvGBROOMwtqmOU7adbbM8FE8LRHnRrKv6OvX3Qs5Kqu4vFY78LW4tPzxbzAdEMAF9rltPcc3Y9D8U8Am7UCQQCg+0Q/Za+HQ5Tgbv9QGYI1tvTUe6WiC3VHcUGmQIqa78baEd7pndcPZuqbnAPVw4oWsuhQEXSakuL+KLGJXZb5AkBE2sANidj99gIiv4e5MCzSe3zYk970zECZa0ZSa+h1/0/K9MEckOtuTOcz9kOjdmw6tXUnJrm19tyYEAACLHedAkAyrATmg8aFqFMzdhzthKoE6GsWezk+0aZ/73l/sG8wp+sK93cYSDPKyFVu1+QpJFzSGkyf726pvTSwVfTUTV5ZAkBWX+yR7VdY3e55rQBQg8k0XhFcldbaN1rZz+a41+smvpxwlslxI+ERH1yY2COUxoZIiD9VhGWudvjca+0tRgXA";
private static volatile ConcurrentHashMap KEY_MAP = new ConcurrentHashMap<>(
2);
/**
* RSA最大加密明文最大大小
*/
public static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* base64解码
*
* @param content
* @return byte[]
* @author compass
* @date 2022/9/1 17:12
* @since 1.0.0
**/
public static byte[] decryptBASE64(String content) {
return Base64Utils.decode(content.getBytes());
}
/**
* base64编码
*
* @param bytes 字符byte数组
* @return java.lang.String
* @author compass
* @date 2022/9/1 17:12
* @since 1.0.0
**/
public static String encryptBASE64(byte[] bytes) {
return new String(Base64Utils.encode(bytes));
}
/**
* 用私钥对信息生成数字签名
*
* @param data 加密数据
* @param privateKey 私钥
* @return java.lang.String
* @author compass
* @date 2022/9/1 14:21
* @since 1.0.0
**/
public static String sign(byte[] data, String privateKey) throws Exception {
// 解密由base64编码的私钥
byte[] keyBytes = decryptBASE64(privateKey);
// 构造PKCS8EncodedKeySpec对象
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
// KEY_ALGORITHM 指定的加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 取私钥匙对象
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 用私钥对信息生成数字签名
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(priKey);
signature.update(data);
return encryptBASE64(signature.sign());
}
/**
* 校验数字签名
*
* @param data 加密数据
* @param publicKey 公钥
* @param sign 数字签名
* @return 校验成功返回true 失败返回false
* @throws Exception
*/
public static boolean verify(byte[] data, String publicKey, String sign)
throws Exception {
// 解密由base64编码的公钥
byte[] keyBytes = decryptBASE64(publicKey);
// 构造X509EncodedKeySpec对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
// KEY_ALGORITHM 指定的加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 取公钥匙对象
PublicKey pubKey = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update(data);
// 验证签名是否正常
return signature.verify(decryptBASE64(sign));
}
/**
* 通过私钥解密
*
* @param data 加密的byte数组
* @param privateKey 私钥
* @return byte[]
* @author compass
* @date 2022/9/1 17:14
* @since 1.0.0
**/
public static byte[] decryptByPrivateKey(byte[] data, String privateKey)
throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(privateKey);
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privatizationKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privatizationKey);
return cipher.doFinal(data);
}
/**
* 通过私钥解密
*
* @param data 加密的byte数组
* @param privateKey 私钥
* @return byte[]
* @author compass
* @date 2022/9/1 17:14
* @since 1.0.0
**/
public static byte[] decryptByPrivateKey(byte[] data, int var1, int var2, String privateKey)
throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(privateKey);
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privatizationKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privatizationKey);
return cipher.doFinal(data, var1, var2);
}
/**
* 私钥分段解密
*
* @param content 加密的内容
* @param privateKey 私钥
* @return java.lang.String
**/
public static String decryptByShort (String content, String privateKey) {
String resultContent = "";
try {
StringBuffer buffer = new StringBuffer();
if (content != null && content.trim().length() > 0) {
String[] contentList = content.split("=");
for (String item : contentList) {
byte[] itemBytes = Base64Utils.decode((item + "=").getBytes());
try {
byte[] itemResultBytes = decryptByPrivateKey(itemBytes, privateKey);
String itemResultStr = new String(itemResultBytes);
buffer.append(itemResultStr);
} catch (Exception e) {
e.printStackTrace();
}
}
}
//base64解密
String res = URLDecoder.decode(buffer.toString());
byte[] result = decryptBASE64(res);
resultContent = new String(result);
} catch (Exception e) {
e.printStackTrace();
System.err.println(
"decryptByShort解密出错:" + e.getMessage() + ":" + "解密内容:" + content);
throw new RuntimeException("rsa解密失败");
}
return resultContent;
}
/**
* 通过私钥解密
*
* @param data 加密的byte数组
* @param privateKey 私钥
* @return byte[]
* @author compass
* @date 2022/9/1 17:14
* @since 1.0.0
**/
public static byte[] decryptByPrivateKey(String data, String privateKey)
throws Exception {
return decryptByPrivateKey(decryptBASE64(data), privateKey);
}
/**
* 公钥分段加密
*
* @param content 加密的内容
* @param publicKey 私钥
* @return java.lang.String
**/
public static String encryptByShort(String content, int maxLength, String publicKey) {
String resultContent = "";
try {
//base64加密
String conBase = new String(Base64Utils.encode(content.getBytes()));
byte[] inputBytes = conBase.getBytes();
int inputLenth = inputBytes.length;
// 标识
int offSet = 0;
StringBuffer buffer = new StringBuffer();
String cache = "";
while (inputLenth - offSet > 0) {
//超出最大字节数分组加密
if (inputLenth - offSet > maxLength) {
cache = encryptByPublicKey(inputBytes, offSet, maxLength, publicKey);
offSet += maxLength;
} else {
//直接加密
cache = encryptByPublicKey(inputBytes, offSet, inputLenth - offSet,
publicKey);
offSet = inputLenth;
}
buffer.append(cache);
}
resultContent = buffer.toString();
} catch (Exception e) {
e.printStackTrace();
System.err.println(
"encryptByShort加密出错:" + e.getMessage() + ":" + "加密内容:" + content);
throw new RuntimeException("rsa解密失败");
}
return resultContent;
}
/**
* 通过公钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static String encryptByPublicKey(String data, String key)
throws Exception {
// 对公钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return encryptBASE64(cipher.doFinal(data.getBytes()));
}
/**
* 通过公钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static String encryptByPublicKey(byte[] data, String key)
throws Exception {
// 对公钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return encryptBASE64(cipher.doFinal(data));
}
/**
* 加密
* 用私钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String key)
throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 通过公钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static String encryptByPublicKey(
byte[] data, int var1, int var2, String key)
throws Exception {
// 对公钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return encryptBASE64(cipher.doFinal(data, var1, var2));
}
/**
* 获取私钥
*
* @param keyMap 存放私钥和公钥的map集合
* @return java.lang.String
* @author compass
* @date 2022/9/1 17:18
* @since 1.0.0
**/
public static String getPrivateKey(Map keyMap) {
PrivateKey key = (PrivateKey) keyMap.get(PRIVATE);
return encryptBASE64(key.getEncoded());
}
/**
* 取得公钥
*
* @param keyMap 放私钥和公钥的map集合
* @return java.lang.String
* @author compass
* @date 2022/9/1 17:28
* @since 1.0.0
**/
public static String getPublicKey(Map keyMap) {
PublicKey key = (PublicKey) keyMap.get(PUBLIC);
return encryptBASE64(key.getEncoded());
}
/**
* 初始化公钥和秘钥 每次调用可以获取不同的公钥和私钥
*
* @return java.util.Map
* @author compass
* @date 2022/9/1 17:28
* @since 1.0.0
**/
public static ConcurrentHashMap initKey() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
ConcurrentHashMap keyMap = new ConcurrentHashMap<>(2);
keyMap.put(PUBLIC, keyPair.getPublic());// 公钥
keyMap.put(PRIVATE, keyPair.getPrivate());// 私钥
return keyMap;
}
/**
* 初始化公钥和秘钥 初始化唯一的公钥和私钥
*
* @return java.util.Map
* @author compass
* @date 2022/9/1 17:28
* @since 1.0.0
**/
public static Map initKeyOnce() {
if (KEY_MAP.size() == 0) {
synchronized (RSAUtil.class) {
if (KEY_MAP.size() == 0) {
try {
KEY_MAP = initKey();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("公钥和私钥初始化失败");
}
}
}
}
return KEY_MAP;
}
public static void main(String[] args) throws Exception {
/*String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCWh3Nyt+5QqUXw1qHXM4k7lq98f9wA4iQgKK1LB1tr4uIgL/dls0LkBgY4oS/Dn3J0qHkpUTkTT84uMHey7cwdd9k90/65cpdawX0J0KO3S3Zwl9d5AJt7/hdSap3AcHw3dvlrZvvDJ72AaR3YUPujNM3dhLC7tsdDb3CxoJSBDQIDAQAB";
String privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJaHc3K37lCpRfDWodcziTuWr3x/3ADiJCAorUsHW2vi4iAv92WzQuQGBjihL8OfcnSoeSlRORNPzi4wd7LtzB132T3T/rlyl1rBfQnQo7dLdnCX13kAm3v+F1JqncBwfDd2+Wtm+8MnvYBpHdhQ+6M0zd2EsLu2x0NvcLGglIENAgMBAAECgYAsR/ZXRfJOOi1/9rOvSdLR+7bt6fL/M4crCqxHyQdEyn54t4OQoFZKG9eSqyAQ7QPPe4wA8orWuoBNqCZeNYP4pXV2ayPwZcUSN9SX4/ce5QZkhHDVBwC8SIQQ7osU6Joh4gR3I+CHlmM1dCItBizOC0Jw4Scs7cpnzzMgYhdPoQJBAO9gzFvGBROOMwtqmOU7adbbM8FE8LRHnRrKv6OvX3Qs5Kqu4vFY78LW4tPzxbzAdEMAF9rltPcc3Y9D8U8Am7UCQQCg+0Q/Za+HQ5Tgbv9QGYI1tvTUe6WiC3VHcUGmQIqa78baEd7pndcPZuqbnAPVw4oWsuhQEXSakuL+KLGJXZb5AkBE2sANidj99gIiv4e5MCzSe3zYk970zECZa0ZSa+h1/0/K9MEckOtuTOcz9kOjdmw6tXUnJrm19tyYEAACLHedAkAyrATmg8aFqFMzdhzthKoE6GsWezk+0aZ/73l/sG8wp+sK93cYSDPKyFVu1+QpJFzSGkyf726pvTSwVfTUTV5ZAkBWX+yR7VdY3e55rQBQg8k0XhFcldbaN1rZz+a41+smvpxwlslxI+ERH1yY2COUxoZIiD9VhGWudvjca+0tRgXA";
String inputStr = "sign";
byte[] data = inputStr.getBytes();
byte[] encodedData = RSAUtil.encryptByPrivateKey(data, privateKey);
String con = "F41sMcJ0umNgZcFzxIzoLY8eZP8vwE5QNq/slHOuft63bWZwANaK8bvHNtac7/qvohEeP2BBPb80wYtToJGSsUegPu2fIlWoyA+JBVDNHRItJNwwNCgbhnBkUR2T8NGRrpjLHoA8dmAh0l9uaoCDog5ZwvHEOLSzTILvY4Rei2U=gB15njJfeQqbNJe2qQ3ui6J88vyjHDL4FKw3KWbY2iXyQM/b+RqT9kgnb0nDhAuZkJ5BWTQorpmyiAQYHaQmz5JgDpZCyw8E4XOXPgZXKgLXkEXwLlhwOhhoH5QsqCieqzu2pG6CcGeYycU+yy2fSs1VPRNIfPpeHde76ZH3urg=YRw5Y0abdEmoaLk0iz44nOPxrO4qBrIBvtBTeAQWv5Dme6YFXOxNIFd63FpE0o5c3nplueDJF17bNbIVT+rAkb54mR/jRXygvosach2ONlM/kw6UaV5lQ+BAAt/+71I7wGqxTvyxz1UFWmIIiYszQxxWIhUxH3hYXY7uHTVOg18=MMLZEy3iNkhZiPuEoLcjRKgVB6HnEY9ywVffY3B/ZBQhUqrONwkjfoh8k5w+xhT7VhMStKCxgfzNNRmKCxvxlLY86nGkZ9l9pkGJqfCQwJSNSP1eYszafgtoOn6/Rc7znPoxxhJ0AWmlcUEB+8PnePO9ApAKai0Jdx4KbpbC7Fg=";
String result = RSAUtil.decryptByShort(con, privateKey);
System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + result);
System.err.println("私钥签名——公钥验证签名");
// 产生签名
String sign = RSAUtil.sign(encodedData, privateKey);
System.err.println("签名:" + sign);
// 验证签名
boolean status = RSAUtil.verify(encodedData, publicKey, sign);
System.err.println("状态:" + status);*/
JSONObject json = new JSONObject();
json.put("idCardNo", "370781111115061010");
json.put("cardType", "2");
json.put("birthday", "2010-03-07");
json.put("graduationArea", "370791");
json.put("householdStatus", "1");
json.put("inoculateEvidence", new ArrayList<>());
json.put("houseStatus", "");
json.put("isKwHouse", "1");
json.put("isSameHousehold", "1");
json.put("name", "张万龙");
String s = "{\"id\":\"20201111113912366\",\"village\":\"东方家园(金马路)\",\"type\":\"1\",\"isSameHousehold\":\"\",\"isGuardianHouse\":\"\",\"arr\":[]}";
//分段加密
/* String encryptContent = RSAUtil.encryptByShort(s,
MAX_ENCRYPT_BLOCK, RSAUtil.PUBLIC_KEY);
System.err.println("加密: " + encryptContent);
//分段解密
String result = RSAUtil.decryptByShort(encryptContent, RSAUtil.PRIVATE_KEY);
System.err.println("解密: " + result);*/
String encrypt = "GmQE3pqs9pMsK4zQ7Oi1SwEaBQK5xKPzc5zrLBJiq3aOp8Y56ttwrdrf5Y/tMazMKZxqL+nAGKA7uIjYjdAO3O1ftQhMHrPStRJKAAgfoH7O8YRhC6DHJqsT70PHtBImMfnAe/BKbbzcjjsLtFTC6mdo7q89sf9zBrsSBAYzj+s=yJ68VZueOmOgKrDEbsthIu+FZqbPU7fAP/292KbGNe2vagfXneQBXmkV7XUCXVpng0nMMRWG6MClaPhCwqHYSF7lKIWTmm2ZJ1o5/9K5EEsvpGn+tIOZIcYEOkAyP4/THx5Stdy+rGWlTdyzLIyPjh1KH2UJcebcCAB0rBqixL0=";
String result = RSAUtil.decryptByShort(encrypt, RSAUtil.PRIVATE_KEY);
System.err.println("解密: " + result);
//初始化公钥私钥
/*Map map = RSAUtil.initKey();
System.err.println("公钥: " +RSAUtil.getPublicKey(map));
System.err.println("密钥: " + RSAUtil.getPrivateKey(map));*/
// System.err.println("base编码: " + encryptBASE64(s.getBytes()));
}
}
RSA接口过滤器:
过滤所有的接口请求,对请求参数进行解密,然后重新设置参数
package com.xinjian.x.common.filter;
import com.alibaba.fastjson.JSONObject;
import com.xinjian.x.common.support.properties.GlobalProperties;
import com.xinjian.x.common.utils.R;
import com.xinjian.x.common.utils.RSAUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
/**
*
* 参数过滤器
*
*
* @author zhengshangjin
* @version 1.0.0
* @since 1.0.0
* created on 2020-04-03
*/
@Slf4j
@Component
public class ServerParamFilter implements Filter {
public boolean isEncryptEnable;
@Override
public void destroy() {
}
@SuppressWarnings("unchecked")
@Override
public void doFilter(
ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//是否加密
if(isEncryptEnable){
HttpServletRequest req = (HttpServletRequest) request;
ParameterRequestWrapper requestWrapper = new ParameterRequestWrapper(req);
String url = req.getServletPath();
boolean isEncrypt = !url.contains("/jygg") && !url.contains("/config") && !url.contains("/files");
if(isEncrypt){
if ("POST".equals(req.getMethod())) {
requestWrapper = handlePostCommonParam(requestWrapper);
}
if ("GET".equals(req.getMethod())) {
requestWrapper = handleGetCommonParam(requestWrapper);
}
}
if (isEncrypt) {
this.encryptResultData(chain,response,requestWrapper);
} else {
chain.doFilter(requestWrapper, response);
}
}else{
chain.doFilter(request, response);
}
}
/**
* @description: 加密返回数据
* @param: [chain,response, requestWrapper]
* @return: void
* @date: 2022/4/12 18:16
*/
public void encryptResultData(FilterChain chain, ServletResponse response, ParameterRequestWrapper requestWrapper) {
// 且对返回数据进行加密 ,此地方代码过于冗余后续可能需要对整个方法进行优化
try {
// 请注意响应处理 包装响应对象 res 并缓存响应数据,只有需要加密数据才使用这个 ResponseWrapper
ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse)response);
// 执行业务逻辑 交给下一个过滤器或servlet处理
// 这里是过滤器注册转发
chain.doFilter(requestWrapper, responseWrapper);
// 是否结果加密
byte[] resData = responseWrapper.getResponseData();
// 设置响应内容格式,防止解析响应内容时出错
responseWrapper.setContentType("application/json;charset=UTF-8");
// 加密响应报文并响应
String data = new String(resData);
JSONObject json = JSONObject.parseObject(data);
// 这里得用原始的流去处理返回 切记
if(null!=json.get("data")&&!"".equals(json.getString("data"))){
String jsonData = json.get("data").toString();
String resultEncrypt = RSAUtil.encryptByShort(jsonData, RSAUtil.MAX_ENCRYPT_BLOCK, RSAUtil.PUBLIC_KEY);
json.put("data",resultEncrypt);
}else{
json.put("data","");
}
PrintWriter out = response.getWriter();
out.print(json.toJSONString());
out.flush();
out.close();
} catch (Exception e) {
log.error("返回数据加密失败:{}", e.getMessage());
try {
getFailResponse((HttpServletResponse)response);
} catch (IOException ioException) {
log.error("io异常:{}", ioException.getMessage());
}
}
}
private void getFailResponse(HttpServletResponse response) throws IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = response.getWriter();
out.write(R.error("服务端加密异常").toString());
out.flush();
out.close();
}
public ParameterRequestWrapper handlePostCommonParam(ParameterRequestWrapper requestWrapper) throws IOException {
// 读取请求内容
BufferedReader br;
br = requestWrapper.getReader();
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line);
}
String params = sb.toString();
JSONObject json = JSONObject.parseObject(params);
params = json.getString("encryptData");
try {
// 解密后的明文
params = RSAUtil.decryptByShort(params, RSAUtil.PRIVATE_KEY);
} catch (Exception e) {
e.printStackTrace();
}
// 把参数转换之后放到我们的body里面
requestWrapper.setBody(params.getBytes("UTF-8"));
return requestWrapper;
}
public ParameterRequestWrapper handleGetCommonParam(ParameterRequestWrapper requestWrapper) {
Map newParams = new HashMap<>();
String params = requestWrapper.getParameter("params");
// 解密后的明文
params = RSAUtil.decryptByShort(params, RSAUtil.PRIVATE_KEY);
String[] pars = params.split("&");
for(int i=0;i1){
newParams.put(par[0], new String[]{par[1]});
}else{
newParams.put(par[0], null);
}
}
requestWrapper.setParameterMap(newParams);
return requestWrapper;
}
@Override
public void init(FilterConfig arg0) throws ServletException {
ServletContext servletContext = arg0.getServletContext();
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
//isEncryptEnable为配置文件的键
String enable= ctx.getEnvironment().getProperty("global.encrypt-enable");
if("true".equals(enable)){
isEncryptEnable = true;
}else{
isEncryptEnable = false;
}
}
}
参数请求设置类:
对请求参数进行处理,包含get和post请求。
package com.xinjian.x.common.filter;
import com.xinjian.x.common.utils.StreamUtil;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;
public class ParameterRequestWrapper extends HttpServletRequestWrapper {
private byte[] body; //用于保存读取body中数据
private Map parameterMap; // 所有参数的Map集合
public ParameterRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
//读取请求的数据保存到本类当中
body = StreamUtil.readBytes(request);
// 给参数集合赋值
parameterMap = request.getParameterMap();
}
/**
* 获取所有参数名
*
* @return 返回所有参数名
*/
@Override
public Enumeration getParameterNames() {
Vector vector = new Vector(parameterMap.keySet());
return vector.elements();
}
/**
* 获取指定参数名的值,如果有重复的参数名,则返回第一个的值 接收一般变量 ,如text类型
*
* @param name 指定参数名
* @return 指定参数名的值
*/
@Override
public String getParameter(String name) {
String result = super.getParameter(name);
return result;
}
/**
* 获取指定参数名的所有值的数组,如:checkbox的所有数据
* 接收数组变量 ,如checkobx类型
*/
@Override
public String[] getParameterValues(String name) {
return parameterMap.get(name);
}
@Override
public Map getParameterMap() {
return parameterMap;
}
public void setParameterMap(Map parameterMap) {
this.parameterMap = parameterMap;
}
//覆盖(重写)父类的方法
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
//覆盖(重写)父类的方法
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public boolean isFinished () {
return false;
}
@Override
public boolean isReady () {
return false;
}
@Override
public void setReadListener (ReadListener readListener) {
}
@Override
public int read() throws IOException {
return bais.read();
}
};
}
/**
* 获取body中的数据
* @return
*/
public byte[] getBody() {
return body;
}
/**
* 把处理后的参数放到body里面
* @param body
*/
public void setBody(byte[] body) {
this.body = body;
}
}
返回请求处理类:
对接口返回信息进行处理。
package com.xinjian.x.common.filter;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.*;
public class ResponseWrapper extends HttpServletResponseWrapper {
/**
* @Description: 响应包装类
* @Date: 2020/5/26 16:29
*/
private ByteArrayOutputStream buffer = null;
private ServletOutputStream out = null;
private PrintWriter writer = null;
public ResponseWrapper(HttpServletResponse response) throws IOException {
super(response);
buffer = new ByteArrayOutputStream();// 真正存储数据的流
out = new WapperedOutputStream(buffer);
writer = new PrintWriter(new OutputStreamWriter(buffer, "utf-8"));
}
/**
* 重载父类获取outputstream的方法
*/
@Override
public ServletOutputStream getOutputStream() throws IOException {
return out;
}
/**
* 重载父类获取writer的方法
*/
@Override
public PrintWriter getWriter() throws UnsupportedEncodingException {
return writer;
}
/**
* 重载父类获取flushBuffer的方法
*/
@Override
public void flushBuffer() throws IOException {
if (out != null) {
out.flush();
}
if (writer != null) {
writer.flush();
}
}
@Override
public void reset() {
buffer.reset();
}
/**
* 将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据
*/
public byte[] getResponseData() throws IOException {
flushBuffer();
return buffer.toByteArray();
}
/**
* 内部类,对ServletOutputStream进行包装
*/
private class WapperedOutputStream extends ServletOutputStream {
private ByteArrayOutputStream bos = null;
public WapperedOutputStream(ByteArrayOutputStream stream) {
bos = stream;
}
@Override
public void write(int b) throws IOException {
bos.write(b);
}
@Override
public void write(byte[] b) throws IOException {
bos.write(b, 0, b.length);
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setWriteListener(WriteListener writeListener) {
}
}
}
过滤器web配置(webconfig):
添加配置过滤器,设置拦截所有请求。
/**
* 配置过滤器
* order属性:控制过滤器加载顺序:数字越小,加载越早
* @return
*/
@Bean
public FilterRegistrationBean ServerParamFilterRegistration() {
//新建过滤器注册类
FilterRegistrationBean registration = new FilterRegistrationBean();
// 添加我们写好的过滤器
registration.setFilter(new ServerParamFilter());
// 设置过滤器的URL模式
registration.addUrlPatterns("/*");
registration.setOrder(Integer.MAX_VALUE - 10);
return registration;
}