代码实现
RSA
package com.test.utils;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import javax.crypto.Cipher;
import sun.misc.BASE64Decoder;
public class RSAUtil {
/*私玥
* MIICXQIBAAKBgQDlOJu6TyygqxfWT7eLtGDwajtNFOb9I5XRb6khyfD1Yt3YiCgQ
WMNW649887VGJiGr/L5i2osbl8C9+WJTeucF+S76xFxdU6jE0NQ+Z+zEdhUTooNR
aY5nZiu5PgDB0ED/ZKBUSLKL7eibMxZtMlUDHjm4gwQco1KRMDSmXSMkDwIDAQAB
AoGAfY9LpnuWK5Bs50UVep5c93SJdUi82u7yMx4iHFMc/Z2hfenfYEzu+57fI4fv
xTQ//5DbzRR/XKb8ulNv6+CHyPF31xk7YOBfkGI8qjLoq06V+FyBfDSwL8KbLyeH
m7KUZnLNQbk8yGLzB3iYKkRHlmUanQGaNMIJziWOkN+N9dECQQD0ONYRNZeuM8zd
8XJTSdcIX4a3gy3GGCJxOzv16XHxD03GW6UNLmfPwenKu+cdrQeaqEixrCejXdAF
z/7+BSMpAkEA8EaSOeP5Xr3ZrbiKzi6TGMwHMvC7HdJxaBJbVRfApFrE0/mPwmP5
rN7QwjrMY+0+AbXcm8mRQyQ1+IGEembsdwJBAN6az8Rv7QnD/YBvi52POIlRSSIM
V7SwWvSK4WSMnGb1ZBbhgdg57DXaspcwHsFV7hByQ5BvMtIduHcT14ECfcECQATe
aTgjFnqE/lQ22Rk0eGaYO80cc643BXVGafNfd9fcvwBMnk0iGX0XRsOozVt5Azil
psLBYuApa66NcVHJpCECQQDTjI2AQhFc1yRnCU/YgDnSpJVm1nASoRUnU8Jfm3Oz
uku7JUXcVpt08DFSceCEX9unCuMcT72rAQlLpdZir876*/
// private static String REQUEST_PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALuYr8WlpQbDmQ1Q" + "O5Wz0f85+UhIH1GHbIwCXU+LoPIX2bqHkzE3B3ZIMSvbCWT5pErv0lyM+7X77TSU" + "42kUC36UysQEu9MwdlVD6RaBVfT6MYoJpvvGgq+VlM82OU3P03e7iDoppsENchlw" + "lr93x6xm/MuyzzRI1BTz0H6+rU1lAgMBAAECgYAdcXN1A/CIxT5KVqNjdZuqAUFc" + "1OUFeMnSl7RpfbK/DHtByXGSsd5b9Cyzg2dQD9Z3ZHiRyhbfkzDBpfSjU2ASMrR0" + "xHGLdJx7DSLd3k75ifF/DECAQA/CzIfiCKa9IgA2Cj//OVLcxjGAw4iEnE9Umsa7" + "n2wyR8bouDarHwifwQJBAPT4IcVaChm0Q8GEZwtyf/FIS0kEQ+u6r2zHja4Nlz+s" + "rR3EwggtV+Me9v2xyJfpcO/mbVyOCdaav17Wr7yD+tkCQQDECzFh0cjviS6wFw8Z" + "+vSWv4IBtGBVbhVB30LQFBMg96b3Av89pULpKRl2mIEVOtfo5IhLaGWhiB4z4Jar" + "QhdtAkEAlZcAaFc3W8LsrTuBAUiGQHz5HDlykHyLq02gguzhs4xqmocQRZYK2TKL"
// + "eRgbekifIp//oElMULRmsC9BWUju4QJAL5qwMRqp+lCLf8L5rctcnUZ/oT5Vrij/" + "DHHUXYaiZnz8lDqsFCIPL2MFheDeZ3NUfn8QAY+mLiVJgDtnGsr/uQJAPmlbiqyY" + "oqrN0Th78PnzOiOmJokLSzOKfg9xpyp4Ae5dGk2tyHsaieIdT+otGAnib5suxodr" + "cSTlMXhIikLimg==";
private static String REQUEST_PRIVATE_KEY = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMRK4nen49xrN8aFLk64lp3Z1fAq6aL0nFhvsWihmzBzTmdyHZ1yeLLpDwxaBjIwsUEybELGcKl5462xcll5nfe9Ho8RG8YFeWANlGpBTaa0kzKgM1Mnl0qdngyvSxrA7fwj0DycFg3h2EDQoxHirW/tti2mILbr9Vyevwz3T8SzAgMBAAECgYBb+MZh0D14gpgwoShQZDbWIUIXdNPhsYEsArF6V/Yx3mUHHTX5FrCtC3wsimXK0HvNE4YcR4R0NBNUyAbPG6fCoOKmqoopmrQALE4lUvJGdNUsqhb6s6/Pwn0LODO36Arw1DS411s3rqb/nW4lEeZie/fVs7ddDInCTw6vInjmaQJBAO2Z1dl1FPHNIlceUl9Kww3HalNndalWSbBjrQqY7bCSnBsHUXEVzwIXrrrLp8EfZ+1r+k2adyjvK9TflVG48pUCQQDTfihlbAQDWB1lgfn2Ci4/trxtFGOpPAf4BH6yM8WJ6wDvPHEur3Pn6IkLaf9YBimHb6CjMFTSUMpDbKaIM5AnAkEApmaYmEUhN/8cT7sSoV4woNPKKUNJ6iBeV0RXihZ0ULc80MkdRn+pjKOdYYEDqYMfO+3lTLgjP+3Q2rMDVkqayQJBAKXb1kpTv4Hv5H3qxODTcxm8cWEKEG50CbvTqpiOSWizx/PWbtyx9C/3CSLOadXaX087l7ri+GJHwZfG6YL/DRkCQA/2mWv6TXlnd4NsgUI2oMfy3qXy+nuisY7JUO/9iRAqq8mV8TzZwePYDR2Iv03Czj/BMpVWIRzBnbNmk07D4i4=";
/**
* 解密算法
* cryptograph:密文
*/
public static String decryptRequestParamValue(String cryptograph) throws Exception {
PrivateKey key = stringToPrivateKey(REQUEST_PRIVATE_KEY);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, key);
BASE64Decoder decoder = new BASE64Decoder();
byte[] b1 = decoder.decodeBuffer(cryptograph);
byte[] b = cipher.doFinal(b1);
return new String(b);
}
public static PrivateKey stringToPrivateKey(String s) {
BASE64Decoder decoder = new BASE64Decoder();
byte[] c = null;
KeyFactory keyFact = null;
PrivateKey returnKey = null;
try {
c = decoder.decodeBuffer(s);
keyFact = KeyFactory.getInstance("RSA");
} catch (Exception e) {
System.out.println("Error in first try catch of stringToPrivateKey");
e.printStackTrace();
}
PKCS8EncodedKeySpec x509KeySpec = new PKCS8EncodedKeySpec(c);
try { // the next line causes the crash
returnKey = keyFact.generatePrivate(x509KeySpec);
} catch (Exception e) {
System.out.println("Error in stringToPrivateKey");
e.printStackTrace();
}
return returnKey;
}
}
package com.test.utils;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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 org.springframework.http.HttpMethod;
public class RsaDecryptRequestParamFilter implements Filter {
private static Field requestField;
private static Field parametersParsedField;
private static Field coyoteRequestField;
private static Field parametersField;
private static Field hashTabArrField;
private List<String> noNeedRsaUrl;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
try {
Class clazz = Class.forName("org.apache.catalina.connector.RequestFacade");
requestField = clazz.getDeclaredField("request");
requestField.setAccessible(true);
parametersParsedField = requestField.getType().getDeclaredField("parametersParsed");
parametersParsedField.setAccessible(true);
coyoteRequestField = requestField.getType().getDeclaredField("coyoteRequest");
coyoteRequestField.setAccessible(true);
parametersField = coyoteRequestField.getType().getDeclaredField("parameters");
parametersField.setAccessible(true);
hashTabArrField = parametersField.getType().getDeclaredField("paramHashValues");
hashTabArrField.setAccessible(true);
noNeedRsaUrl = Arrays.asList(replaceBlank(filterConfig.getInitParameter("noNeedRsaUrl")).split(","));
System.out.println("RsaFilter初始化完成,不需要解密的Post方法为:{}"+ noNeedRsaUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("公共Rsa解密Filter");
HttpServletRequest req = (HttpServletRequest) servletRequest;
servletResponse.setCharacterEncoding("UTF-8");
String url = ((HttpServletRequest) servletRequest).getServletPath();
System.out.println("请求Url:{}" + url);
System.out.println("NoNeedRsaUrl:{}"+noNeedRsaUrl);
if (!noNeedRsaUrl.contains(url)) {
System.out.println("Url:{}不在noNeeRsaUrl中,开始解密"+url);
Object rsaKey = servletRequest.getParameter("data");
if (req.getMethod().equals(HttpMethod.POST.name())) {
if (null != rsaKey) {
String[] params;
try {
String paramValue = RSAUtil.decryptRequestParamValue((String) rsaKey);
System.out.println("解密完成:params:{}"+ paramValue);
params = paramValue.split("&");
} catch (Exception e) {
e.printStackTrace();
servletResponse.getWriter().write("{\"code\":\"403\",\"message\":\"密文错误\"}");
return;
}
Map<String, ArrayList<String>> requestParamtersMap = getRequestMap(servletRequest);
for (int i = 0; i < params.length; i++) {
String[] param = params[i].split("=");
if (param.length == 2){
ArrayList list = new ArrayList<>();
list.add(URLDecoder.decode(param[1], "UTF-8"));
requestParamtersMap.put(param[0], list);
}
}
} else {
servletResponse.getWriter().write("{\"code\":\"403\",\"message\":\"缺少密文\"}");
return;
}
}
}
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
private Map<String, ArrayList<String>> getRequestMap(ServletRequest request) {
try {
Object innerRequest = requestField.get(request);
parametersParsedField.setBoolean(innerRequest, true);
Object coyoteRequestObject = coyoteRequestField.get(innerRequest);
Object parameterObject = parametersField.get(coyoteRequestObject);
return (Map<String, ArrayList<String>>) hashTabArrField.get(parameterObject);
} catch (IllegalAccessException e) {
e.printStackTrace();
return Collections.emptyMap();
}
}
public String replaceBlank(String str) {
String dest = "";
if (str!=null) {
Pattern p = Pattern.compile("\\s*|\t|\r|\n");
Matcher m = p.matcher(str);
dest = m.replaceAll("");
}
return dest;
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>dj_rsa</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>chapter2</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-controller.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>chapter2</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>rsa</filter-name>
<filter-class>com.bw.test.utils.RsaDecryptRequestParamFilter</filter-class>
<init-param>
<description>不需要加密的post请求,多个用逗号分隔</description>
<param-name>noNeedRsaUrl</param-name>
<param-value>
/login1.action
</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>rsa</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 乱码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>