在平時做項目時,大多都是用的頁面的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