Android資料轉送增加簽名認證(防止資料被篡改)
我們開發的用戶端項目,跟伺服器通訊的時候,一般都是HTTP明文的形式進行的,這樣的資料很容易被別人截取,如果被截取的資訊是比較敏感的資料,並且資料沒有進行加密,被隨意的篡改成,那後果不堪設想。還好,目前來說有比較好的簽名演算法,下面是PHP版本的(資料驗證就是用下面的方法):
演算法的原理是這樣的:假設我們請求的網址是http://xxxx.com,要傳過去的資料是username=bb, action=buy, gid=10這三個購買邏輯的參數,我們該如何對這個資料進行簽名呢?首先,我們用戶端要有一個跟伺服器相同的key(密鑰),key是打死都不能告訴別人的!用這個key我們產生一個sign(簽名),簽名演算法是:
sign = md5("username="+bb+"&"+"action="+buy+"&gid="+10"+key)
然後我們把username,action,gid,sign一同傳過去,伺服器那邊進行解析我們傳過去的參數,然後用上面相同的演算法,產生sign_new,跟我們傳過去的sign進行對比,如果相同,說明資料沒有被篡改,如果不同,說明資料被改動過,不合法,該操作被拒絕!
光說不上代碼的,那都是耍流氓···好,廢話不說了,下面是PHP版本的:
/** * 作用:格式化參數,簽名過程需要使用 */function formatBizQueryParaMap($paraMap, $urlencode){$buff = "";ksort($paraMap);foreach ($paraMap as $k => $v){ if($urlencode) { $v = urlencode($v);}//$buff .= strtolower($k) . "=" . $v . "&";$buff .= $k . "=" . $v . "&";}$reqPar;if (strlen($buff) > 0) {$reqPar = substr($buff, 0, strlen($buff)-1);}return $reqPar;}/** * 作用:產生簽名 */public function getSign($Obj){foreach ($Obj as $k => $v){$Parameters[$k] = $v;}//簽名步驟一:按字典序排序參數ksort($Parameters);$String = formatBizQueryParaMap($Parameters, false);//echo '【string1】'.$String.'';//簽名步驟二:在string後加入KEY$String = $String."&key=".Config::KEY;//echo "【string2】".$String."";//簽名步驟三:MD5加密$String = md5($String);//echo "【string3】 ".$String."";//簽名步驟四:所有字元轉為大寫$result_ = strtoupper($String);//echo "【result】 ".$result_."";return $result_;}
下面是android版本的:
public static> List asSortedList(Collection c) { List list = new ArrayList(c); java.util.Collections.sort(list); return list;}public static String formatBizQueryParaMap(Map paraMap){Set keys = paraMap.keySet();List sorted = asSortedList(keys);StringBuffer buffer=new StringBuffer();for(String key : keys){buffer.append(key+"="+paraMap.get(key)+"&");}String result = "";if (buffer.length() > 0) {result = buffer.substring(0, buffer.length()-1);}return result;}/** * 作用:產生簽名 */public static String getSign(Map paraMap){String params = formatBizQueryParaMap(paraMap);params = params+"&key="+"11111";String md5 = toMD5(params.getBytes());return md5.toUpperCase();}public static String toMD5(byte[] source) { try{ MessageDigest md = MessageDigest.getInstance("MD5"); md.update( source ); StringBuffer buf=new StringBuffer(); for(byte b:md.digest()) buf.append(String.format("%02x", b&0xff) ); return buf.toString(); }catch( Exception e ){ e.printStackTrace(); return null; } }