現在應用開發中通常會用到介面,其資料是通過開放的互連網傳輸,對資料的安全性有一定要求,為了防止資料在傳輸過程中被篡改,常用資料簽名(sign)的方式來校正。
資料簽名sign產生方法
①去除數組中的空值和簽名參數(sign/sign_type)
②按鍵名升序排列數組
③把數組所有元素,按照“參數=參數值”的模式用“&”字元拼接成字串
④把拼接後的字串再與安全校正碼直接連接起來
⑤MD5等加密函數,加密字串
範例程式碼
class Sign {
/**
* 擷取資料簽名
*
* @param array $param 簽名數組
* @param string $code 安全校正碼
* @param string $sign_type 簽名類型
* @return string 簽名字串
*/
public static function getSign($param, $code, $sign_type = 'MD5'){
//去除數組中的空值和簽名參數(sign/sign_type)
$param = self::paramFilter($param);
//按鍵名升序排列數組
$param = self::paramSort($param);
//把數組所有元素,按照“參數=參數值”的模式用“&”字元拼接成字串
$param_str = self::createLinkstring($param);
//把拼接後的字串再與安全校正碼直接連接起來
$param_str = $param_str . $code;
//建立簽名字串
return self::createSign($param_str, $sign_type);
}
/**
* 校正資料簽名
*
* @param string $sign 介面收到的簽名
* @param array $param 簽名數組
* @param string $code 安全校正碼
* @param string $sign_type 簽名類型
* @return boolean true正確,false失敗
*/
public static function checkSign($sign, $param, $code, $sign_type = 'MD5'){
return $sign == self::getSign($param, $code, $sign_type);
}
/**
* 去除數組中的空值和簽名參數
*
* @param array $param 簽名數組
* @return array 去掉空值與簽名參數後的新數組
*/
private static function paramFilter($param){
$param_filter = array();
foreach ($param as $key => $val) {
if($key == 'sign' || $key == 'sign_type' || !strlen($val)){
continue;
}
$param_filter[$key] = $val;
}
return $param_filter;
}
/**
* 按鍵名升序排列數組
*
* @param array $param 排序前的數組
* @return array 排序後的數組
*/
private static function paramSort($param){
ksort($param);
reset($param);
return $param;
}
/**
* 把數組所有元素,按照“參數=參數值”的模式用“&”字元拼接成字串
*
* @param array $param 需要拼接的數組
* @return string 拼接完成以後的字串
*/
private static function createLinkstring($param){
$str = '';
foreach ($param as $key => $val) {
$str .= "{$key}={$val}&";
}
//去掉最後一個&字元
$str = substr($str, 0, strlen($str) - 1);
//如果存在逸出字元,那麼去掉轉義
if(get_magic_quotes_gpc()){
$str = stripslashes($str);
}
return $str;
}
/**
* 建立簽名字串
*
* @param string $param 需要加密的字串
* @param string $type 簽名類型 預設值:MD5
* @return string 簽名結果
*/
private static function createSign($param, $type = 'MD5'){
$type = strtolower($type);
if($type == 'md5'){
return md5($param);
}
if($type == 'dsa'){
exit('DSA 簽名方法待後續開發,請先使用MD5簽名方式');
}
exit("介面暫不支援" . $type . "類型的簽名方式");
}
}