工具类——简单的AES128加密参数过滤器(spring boot)

maven

        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.9</version>
        </dependency>

在spring boot的启动类中加入注解

@ServletComponentScan

IdentifyingCodeFilter 类

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


/**
 * <p class="detail">
 * 功能:验证码校验过滤
 * </p>
 *
 * @ClassName: IdentifyingCodeFilter
 */
 // @Order该注解的参数表示多个过滤器的执行顺序,越小则优先执行
 // @WebFilter 的 urlPatterns 可以写多个url,如 urlPatterns ={"/test1","test2"}
@Order(1)
@WebFilter(filterName = "identifyingCodeFilter",urlPatterns = "/*")
public class IdentifyingCodeFilter implements Filter {
    static Logger log = LoggerFactory.getLogger(IdentifyingCodeFilter.class);

    String[] strUrl = {"/codeFilter" };


    @Override
    public void init(FilterConfig arg0) throws ServletException {
        log.info("执行校验过滤器IdentifyingCodeFilterr--init方法完成");

    }

    @Override
    public void destroy() {
        log.info("执行校验过滤器IdentifyingCodeFilter--destroy方法完成");

    }

    /**
     * <p class="detail">
     * 功能:过滤 接口
     * </p>
     * @param req
     * @param res
     * @param chain
     * @throws IOException
     * @throws ServletException
     * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
     *      javax.servlet.ServletResponse, javax.servlet.FilterChain)
     */
    @Override
    public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        req.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        boolean b = false;
        String userName = req.getParameter("userName");
        String url = request.getRequestURI();
        for (int i = 0; i < strUrl.length; i++) {
            if(url.contains(strUrl[i])){
                b = true;
                break;
            }
        }
        if (b) {
            try {
                Map<String, String[]> m = new HashMap<>(request.getParameterMap());
                if(StringUtils.isNotBlank(userName)) {
                    /**变更request的参数**/
                    String tParam = AES128.decryptAES(userName.replaceAll(" ","+"), "7t3e506jaa10xbd4");
                    m.put("userName", new String[]{tParam});
                    /**解密后的参数重新放入request*/
                    ParameterRequestWrapper prw = new ParameterRequestWrapper(request, m);
                    request = prw;
                    chain.doFilter(request, response);
                }

            } catch (Exception e) {
                // 这里写业务逻辑
                System.out.println("参数校验未通过");
            }
        } else {
            chain.doFilter(request, response);
        }
        log.info("执行校验过滤器IdentifyingCodeFilter--doFilter方法完成");

    }

}

ParameterRequestWrapper 类

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;

public class ParameterRequestWrapper extends HttpServletRequestWrapper {

    private Map<String, String[]> params;

    public ParameterRequestWrapper(HttpServletRequest request, Map<String, String[]> newParams) {
        super(request);
        this.params = newParams;
        //addParameterMap(request);
    }

    @Override
    public String getParameter(String name) {
        String result = "";

        Object v = params.get(name);
        if (v == null) {
            result = null;
        } else if (v instanceof String[]) {
            String[] strArr = (String[]) v;
            if (strArr.length > 0) {
                result = strArr[0];
            } else {
                result = null;
            }
        } else if (v instanceof String) {
            result = (String) v;
        } else {
            result = v.toString();
        }

        return result;
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        return params;
    }

    @Override
    public Enumeration<String> getParameterNames() {
        return new Vector<String>(params.keySet()).elements();
    }

    @Override
    public String[] getParameterValues(String name) {
        String[] result = null;

        Object v = params.get(name);
        if (v == null) {
            result = null;
        } else if (v instanceof String[]) {
            result = (String[]) v;
        } else if (v instanceof String) {
            result = new String[] { (String) v };
        } else {
            result = new String[] { v.toString() };
        }

        return result;
    }


}

AES128 类

import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Decoder;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;

/**
 * <p>
 * 功能:AES128位对称加密类,该类参数需要16位字符串秘钥及待加/解密字符串
 * <br/>参考文章:
 * http://blog.csdn.net/coyote1994/article/details/52368921
 * <br/>http://jueyue.iteye.com/blog/1830792
 * </p>
 * @ClassName: AES128
 */
public class AES128 {
    /**
     * 定义一个初始向量,需要与iOS端的统一,使用CBC模式,需要一个向量iv,可增加加密算法的强度
     */
    private static final String IV_STRING = "16-Bytes--String";

    /**
     * <p class="detail">
     * 功能:AES128加密方法
     * </p>
     * @author tangy
     * @date 2016年10月27日
     * @param content 待加密内容
     * @param key 加密密钥(16位字符串)
     * @return 加密后的字符串(结果已经过base64加密)
     * @throws Exception
     */
    public static String encryptAES(String content, String key)
            throws Exception {
        byte[] byteContent = content.getBytes("UTF-8");
        // 注意,为了能与 iOS 统一
        // 这里的 key 不可以使用 KeyGenerator、SecureRandom、SecretKey 生成
        byte[] enCodeFormat = key.getBytes();
        SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
        byte[] initParam = IV_STRING.getBytes();
        IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
        // 指定加密的算法、工作模式和填充方式
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] encryptedBytes = cipher.doFinal(byteContent);
        // 同样对加密后数据进行 base64 编码
        return Base64.encodeBase64String(encryptedBytes);
    }

    /**
     * <p class="detail">
     * 功能:解密函数
     * </p>
     * @param content 待解密字符串
     * @param key 解密秘钥(16位字符串,需要与加密字符串一致)
     * @return
     * @throws Exception
     */
    public static String decryptAES(String content, String key)
            throws Exception {
        // 先base64 解码
        byte[] encryptedBytes = Base64.decodeBase64(content);
        byte[] enCodeFormat = key.getBytes();
        SecretKeySpec secretKey = new SecretKeySpec(enCodeFormat, "AES");
        //使用CBC模式,需要一个向量iv,可增加加密算法的强度
        byte[] initParam = IV_STRING.getBytes();
        IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
        //"算法/模式/补码方式"
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
        byte[] result = cipher.doFinal(encryptedBytes);
        if(result.length==0){
            throw new IllegalBlockSizeException();
        }
        return new String(result, "UTF-8");
    }

    /**
     * 测试函数
     */
    public static void main(String[] args) throws Exception {
        String content="15957491727";
        //必须为16位
        String key="7t3e506jaa10xbd4";
        String deKey="7t3e506jaa10xbd4";
        String enstring = encryptAES(content, key);
        String destring = decryptAES(enstring,deKey);
        System.out.println("原始字符串:"+content);
        System.out.println("加密后字符串:"+enstring);
        System.out.println("长度:"+enstring.length());
        System.out.println("解密后字符串:"+destring);

    }
}

猜你喜欢

转载自blog.csdn.net/chineseyoung/article/details/81119959