在平时做项目时,大多都是用的页面的Form表单提交方式,以及前台Jquery.ajax方式提交请求,但是有的时候这两种提交方式不能满足所有的需求,有的需要异步请求,更何况IE地址栏的长度也是有限制的。比如你需要写一个开放的接口,需要第三方按照你的规则提交访问你的开放接口,这个时候你就会想到,如果所有的参数都放到页面的地址上来请求这样子无疑是暴露的,安全性非常低,因此这时,你需要把请求置于后台用java来提交post或者get请求了;
可能你会觉得这样已经没没问题了,你要知道所谓道高一尺魔高一丈的道理,例如所谓的暴力破解这些都是当有人利用嗅探器嗅探出你的提交地址了以后(嗅探器,你要知道12306购票网站最近新起的订票助手之类的插件归根结底都需要知道每一个有用的提交地址,才能达到智能化的订票流程,因此订票助手才能如此强大)加上你需要的参数,简单的说,写个循环,加上算法,就可以无限制的请求你的地址,直至破解为止;
这显然是一个很大的漏洞,因此在请求的过程中,我们需要涉及加入你的加密key进行加密传输,然后进行参数解密,这样既能隐藏你的请求,也能做到防止篡改,和时间戳的比较;
如何加密?以前我曾经开发过一个通用的快捷支付接口,因为快捷支付目前市场上有太多太多,各大银行都有对应的接口,而且参数不同,因此需要开发一个有固定规范的工程来控制不同的参数传递,从中我学到了一些简单的有效的加密方式,这里给大家分享一下,例如:你的地址是http://www.***.com/ceshi.do?a=1&b=2&time=201201010,这样的地址是很容易被嗅探到进行串改的,假设如果a参数是某购物网站的购物卷ID,你需要用此参数进行购物优惠,这样一旦被改你的麻烦就大了,因此你需要将参数部分进行MD5(a=1&b=2&time=201201010)加密,最后将加密好的字符串一起随参数传递给你的接口进行对应的解密比对,这时请求地址应该是:http://www.***.com/ceshi.do?a=1&b=2&time=201201010&sign=XJDEKL2301941,这样如果请求的参数被篡改,你也可以拿前面的参数进行拼接加密,最后和预先加密好的sign进行比对,如果不一致则被篡改,time参数更可以解决防止多次恶意提交的问题;
这只是一种很简单的加密方式,很显然效果显著,因为MD5加密是不可解的,下面介绍我在另一个项目中看到的第二种加密方式:URL(URL(BASE64(DES(字符串)))),解释一下,最先用DES+私有KEY进行加密,然后BASE64进行加密,最后两次URL加密过滤中文回车等符号,加密完成以后,用java的post方式进行传递参数,因为这种加密方式会使原本很短的参数变的很长,服务器端接收到这样的加密方式解密也很简单(这里要注意一下:加密时用的编码方式,如果是用UTF-8进行加密,则解密也需要按照顺序用UTF-8进行解密):URL(BASE64(DES(加密字符串))),最后用new String(“解密好的byte数组”,“UTF-8”)进行编码一次即可,这里可能有人会问,为什么会是一个数组,这个用过DES加密的人都知道。
好了,聊了这么多关于传递安全性的问题,这里讲一个我在接收参数中遇见的问题:当客户端采用java后台post以流的方式传递DES加密参数时(传递的并非字符串,而是byte数组),服务端接收参数时,需要用字节的方式去获取流中的byte数组,如下:
StringBuffer sb_ = new StringBuffer() ;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b = new byte[4096];
int len;
while ((len = is.read(b)) != -1) {
baos.write(b, 0, len);
}
baos.close();
is.close();
byte[] data = baos.toByteArray();
而非如下方式去获取(因为客户端传递过来的并非是一个字符串,而是一个byte的加密数组)
StringBuffer sb = new StringBuffer() ;
InputStream is = request.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr,"UTF-8");
String s = "" ;
while((s=br.readLine())!=null){
sb.append(s) ;
}
//或者一句话
BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(),"UTF-8")); String s = "" ;
while((s=br.readLine())!=null){
sb.append(s) ;
}
提供下载地址(DES加密、BASE64机密工具,HTTP请求工具类)
http://pan.baidu.com/share/link?shareid=180141&uk=1443215090
解压密码:weiwei
参考资料:
使用Java发送POST、GET请求
http://hi.baidu.com/cn_rigel/item/e7c934589bda410ce7c4a5ce
IE地址栏的最大长度
http://www.ooso.net/archives/244
原创帖,转载请注明:http://blog.csdn.net/weiweicissy_2012/article/details/8534435