RSA分段加密解密

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;
    }

你可能感兴趣的:(java,java,servlet,开发语言)