Java 过滤器:解码 ServletRequest,处理解码后的数据,获取并编码结果和响应用户

问题描述 投票:0回答:1

我正在使用 Spring 创建一个安全的 Java Web 应用程序。为此,我使用 AES 加密来解密和加密请求、响应数据。

我想为这个功能使用过滤器。 这是流程:

  1. 带有加密数据的用户请求
  2. 过滤器中的数据解密
  3. 带有解密数据的请求控制器
  4. 获取并加密响应
  5. 向请求者提供加密响应。

我可以解密请求数据并加密响应。但我不知道如何将解密数据发送到我的控制器。请查看附图以获取更多信息。 提前致谢!

java spring encryption servlet-filters
1个回答
0
投票

我们为请求创建包装类扩展 HttpServletRequestWrapper 和响应扩展 HttpServletResponseWrapper 然后创建你的加密解密逻辑类

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class RequestWrapper extends HttpServletRequestWrapper {

    private final String body;

    public RequestWrapper(HttpServletRequest request) throws Exception {
        super(request);

        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        try {
            InputStream inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {
            throw ex;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException ex) {
                    throw ex;
                }
            }
        }
        String encryptData = stringBuilder.toString();
        String deCryptData = null;
        if (encryptData != null && !encryptData.isEmpty()) {
            deCryptData = DecryptEncryptData.decrypt(encryptData);
            if (deCryptData == null) {
                //Exception occured inside decrypt - Request Body not valid:
            }
        }
        body = deCryptData;
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
        ServletInputStream servletInputStream = new ServletInputStream() {
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }

            public boolean isFinished() {
                // TODO Auto-generated method stub
                return false;
            }

            public boolean isReady() {
                // TODO Auto-generated method stub
                return false;
            }

            public void setReadListener() {
                // TODO Auto-generated method stub
            }
        };
        return servletInputStream;
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }

    public String getBody() {
        return this.body;
    }
}

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class ResponseWrapper extends HttpServletResponseWrapper {

    private ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    private PrintWriter writer = new PrintWriter(outputStream);
    
    public ResponseWrapper(HttpServletResponse response) {
        super(response);
        // TODO Auto-generated constructor stub
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {

        return new ServletOutputStream() {
            @Override
            public void write(int b) throws IOException {
                outputStream.write(b);
            }

            @Override
            public void write(byte[] b) throws IOException {
                outputStream.write(b);
            }
        };
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        return writer;
    }

    @Override
    public void flushBuffer() throws IOException {
        if (writer != null) {
            writer.flush();
        } else if (outputStream != null) {
            outputStream.flush();
        }
    }

    public String getResponseData() {
        return outputStream.toString();
    }

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.OutputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ApiFilter implements Filter{

    @Override
    public void init(FilterConfig arg0) throws ServletException {       
    }
    @Override
    public void destroy() {     
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        RequestWrapper requestWrapper = null;
        ResponseWrapper responseWrapper = null;
        try {
            requestWrapper = new RequestWrapper(httpServletRequest);
            responseWrapper = new ResponseWrapper(httpServletResponse);
            chain.doFilter(requestWrapper, responseWrapper);
        } catch (Exception e) {

        }  
        
        String responseData = responseWrapper.getResponseData();
        String encryptedResponseData = "";
        try {
            encryptedResponseData = DecryptEncryptData.encrypt(responseData);
        } catch (InvalidKeyException e) {

        } catch (NoSuchPaddingException e) {

        } catch (NoSuchAlgorithmException e) {

        } catch (InvalidAlgorithmParameterException e) {

        } catch (BadPaddingException e) {

        } catch (IllegalBlockSizeException e) {

        }
        OutputStream outputStream = httpServletResponse.getOutputStream();
        outputStream.write(encryptedResponseData.getBytes());
        outputStream.flush();
        outputStream.close();
    }

}

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class DecryptEncryptData {

    private final static String KEY = "";// provide your key
    private final static String IV = "";// provide your vector key
    private final static String algorithm = "";// provide your algorithm
    

    public static String encrypt(String plainText) throws NoSuchPaddingException, NoSuchAlgorithmException,
            InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {

        SecretKey key = new SecretKeySpec(KEY.getBytes(), "AES");
        IvParameterSpec iv = new IvParameterSpec(IV.getBytes());
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
        byte[] cipherText = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(cipherText);
    }

    public static String decrypt(String cipherText) throws NoSuchPaddingException, NoSuchAlgorithmException,
            InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {

        SecretKey key = new SecretKeySpec(KEY.getBytes(), "AES");
        IvParameterSpec iv = new IvParameterSpec(IV.getBytes());
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.DECRYPT_MODE, key, iv);
        byte[] plainText = cipher.doFinal(Base64.getDecoder().decode(cipherText));
        return new String(plainText);
    }

}

© www.soinside.com 2019 - 2024. All rights reserved.