您的位置:首页 > 编程语言 > Java开发

springmvc 部分加密通信

2016-03-30 12:23 357 查看
手机客户端与后台交互中一般会用到加密传输。至于不用HTTPS,本文不讨论,这里给出使用springmvc +http协议,手机客户端加密部分数据值,后台进行统一解密。实现思路就是使用拦截器,使用装饰模式,可以直接使用HttpServletRequestWrapper。

springmvc后台DES3 解密

原文和密文前后均无空格

数据

#1

原文: karl

密文:HM6LxeRjJxc=

UR编码: HM6LxeRjJxc%3d

#2

原文: del555

密文: HNf8wVhKhsg=

UR编码: HNf8wVhKhsg%3d

#3

原文:

在MIME格式的电子邮件中,base64可以用来将binary的字节序列数据编码成ASCII字符序列构成的文本。使用时,在传输编码方式中指定base64。然后,每次取出6个bit


密文:

eT9O6eHyB27BKL7u4eXE49xoGZZ4aZdQ3ibZ4uKvlD8yLwCeKJi9SYijf142uufEB36d/sk6VmuOd8c8WHspd3kba490j/3+Dez03ycGzNssE4MwuNApSdyQ5BDZTLq7fkxwn+MvkIJTGiwgPcdD8xEMEWgp6/s9gENhWGGnayBfWrSv/36pBNNVhb+HkKXlwPCAazIVbFK4CrohlviiJ3lJv7/qfFlPNPUAVQYAWbGBJ7vA4osfspzMb0abw3uXSROm7KYopKu9KRe9Cgxs7w==


密文URL编码后:

eT9O6eHyB27BKL7u4eXE49xoGZZ4aZdQ3ibZ4uKvlD8yLwCeKJi9SYijf142uufEB36d%2Fsk6VmuOd8c8WHspd3kba490j%2F3%2BDez03ycGzNssE4MwuNApSdyQ5BDZTLq7fkxwn%2BMvkIJTGiwgPcdD8xEMEWgp6%2Fs9gENhWGGnayBfWrSv%2F36pBNNVhb%2BHkKXlwPCAazIVbFK4CrohlviiJ3lJv7%2FqfFlPNPUAVQYAWbGBJ7vA4osfspzMb0abw3uXSROm7KYopKu9KRe9Cgxs7w%3D%3D


或者

密文RFC822格式(76个字符一行):

eT9O6eHyB27BKL7u4eXE49xoGZZ4aZdQ3ibZ4uKvlD8yLwCeKJi9SYijf142uufEB36d/sk6VmuO
d8c8WHspd3kba490j/3+Dez03ycGzNssE4MwuNApSdyQ5BDZTLq7fkxwn+MvkIJTGiwgPcdD8xEM
EWgp6/s9gENhWGGnayBfWrSv/36pBNNVhb+HkKXlwPCAazIVbFK4CrohlviiJ3lJv7/qfFlPNPUA
VQYAWbGBJ7vA4osfspzMb0abw3uXSROm7KYopKu9KRe9Cgxs7w==


密文RFC822格式URL编码后:

eT9O6eHyB27BKL7u4eXE49xoGZZ4aZdQ3ibZ4uKvlD8yLwCeKJi9SYijf142uufEB36d%2fsk6VmuO%0ad8c8WHspd3kba490j%2f3%2bDez03ycGzNssE4MwuNApSdyQ5BDZTLq7fkxwn%2bMvkIJTGiwgPcdD8xEM%0aEWgp6%2fs9gENhWGGnayBfWrSv%2f36pBNNVhb%2bHkKXlwPCAazIVbFK4CrohlviiJ3lJv7%2fqfFlPNPUA%0aVQYAWbGBJ7vA4osfspzMb0abw3uXSROm7KYopKu9KRe9Cgxs7w%3d%3d


测试

使用已以上数据进行测试

springmvc, phone 使用原文, 其他三个使用加密数据

@Controller
public class IndexController {

@RequestMapping("/")
@ResponseBody
Object index(String phone, String name, String password, String desc) {
System.out.println("-----------------------------------------");
System.out.println("phone:" + phone);
System.out.println("name:" + name);
System.out.println("password:" + password);
System.out.println("desc:" + desc);
return "Hello longdai!";
}
}


POST:

参数
phone131212345678
nameHM6LxeRjJxc%3d
passwordHNf8wVhKhsg%3d
desc
这里使用数据#3的URL编码后的数据
期望结果:

-----------------------------------------
phone:131212345678
name:karl
password:del555
desc:在MIME格式的电子邮件中,base64可以用来将binary的字节序列数据编码成ASCII字符序列构成的文本。使用时,在传输编码方式中指定base64。然后,每次取出6个bit


POSTMAN:



结果:



解密拦截器源码:

@Configuration
public class DecryptFilter extends OncePerRequestFilter {
private static Log log = LogFactory.getLog(DecryptFilter.class);

private static Pattern BASE64_PATTERN = Pattern.compile("^[a-zA-Z0-9\\+/]+[=]{0,2}$");
private static Pattern BASE64_PATTERN_RFC822 = Pattern.compile("^[a-zA-Z0-9\\+/\n]+[=]{0,2}$");

public String filter(HttpServletRequest request, String name, String input) {
String ret = input;
if (input == null || input.trim().equals("(null)")) {
return null;
}
boolean b1 = input.length()%4==0 && BASE64_PATTERN.matcher(input).matches();
boolean b2 = input.length() > 77 && input.charAt(76)=='\n' && BASE64_PATTERN_RFC822.matcher(input).matches();
if ( !b1 && !b2){
return injectSQLFilter(name, input);//not base64 text
}
try {
ret = Des3.decode(input);
} catch (Exception e) {
log.error(request.getRequestURI() + " error decode " + name + "=" + input, e);
}
return injectSQLFilter(name, ret);
}

public String injectSQLFilter(String name, String text){
if(text==null){
return null;
}
if(name.matches("password|passwd|loginPassword|dealPassword")){
return text;
}
//TODO 这里处理SQL注入,直接处理掉注入数据,或者下层拦截器处理
return text;
}

@Override
protected void doFilterInternal(final HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {

chain.doFilter(new HttpServletRequestWrapper(request) {

protected Map<String, String[]> parameters = new HashMap<String, String[]>();
@Override
public String getParameter(String name) {
if (parameters.containsKey(name)){
String[] values = parameters.get(name);
if (values!=null && values.length>0){
return values[0];
}
}
String value = super.getParameter(name);
String retValue = filter(this, name, value);
parameters.put(retValue, new String[]{retValue});
return retValue;
}

@Override
public String[] getParameterValues(String name) {
if (parameters.containsKey(name)){
String[] values = parameters.get(name);
return values;
}
String[] values = super.getParameterValues(name);
if (values == null) {
return null;
}
for (int i = 0; i < values.length; i++) {
values[i] = filter(this, name, values[i]);
}
parameters.put(name, values);
return values;
}

}, response);

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: