我正在使用 Spring 创建一个安全的 Java Web 应用程序。为此,我使用 AES 加密来解密和加密请求、响应数据。
我想为这个功能使用过滤器。 这是流程:
我们为请求创建包装类扩展 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);
}
}