api接口安全验证-传输密文
示意图

原理
从图中可以看得很清楚,前台想要调用接口,需要使用几个参数生成签名。
时间戳:当前时间
随机数:随机生成的随机数(最好是唯一)
私钥:服务端分配给前端的私钥(附带的还会有一个公钥,公钥作为请求参数传给服务端)
算法规则:商定好的运算规则,利用算法规则生成一个签名。
前台生成一个签名,当需要访问接口的时候,把时间戳,随机数,公钥,请求参数,签名传递到后台。后台拿到这些数据之后,通过一样的算法规则计算出签名,然后和传递过来的签名进行对比,一样的话,返回数据。
算法规则
签名步骤一:拼接获取到的参数,并按字典序排序参数,得到一个string
签名步骤二:在string后加入KEY=私钥
签名步骤三:MD5加密
签名步骤四:所有字符转为小写
/**
* 作用:生成签名
* @param array $params
* @return bool
*/
public function getSign($params = array())
{
$private_key = $this->key[$params['public_key']];
$reqSign = $params['sign'];
unset($params['sign']); //sign不参与签名
unset($params['public_key']); //公钥不参与签名
//对参数按key,升序排序
ksort($params, SORT_STRING);
$queryStr = http_build_query($params);
$sign = strtolower(md5($queryStr . "&key=" . $private_key));
if ($reqSign == $sign) {
return true;
}
//兼容rfc 3986 urlencode兼容
$queryStr = http_build_query($params, '', '&', PHP_QUERY_RFC3986);
$sign = strtolower(md5($queryStr . "&key=" . $private_key));
if ($sign == $reqSign) {
return true;
} else {
if (strpos($queryStr, '%28')) {
$queryStr = str_replace('%28', '(', $queryStr);
}
if (strpos($queryStr, '%29')) {
$queryStr = str_replace('%29', ')', $queryStr);
}
if (strpos($queryStr, '%7E')) {
$queryStr = str_replace('%7E', '~', $queryStr);
}
if (strpos($queryStr, '%21')) {
$queryStr = str_replace('%21', '!', $queryStr);
}
if (strpos($queryStr, '%2A')) {
$queryStr = str_replace('%2A', '*', $queryStr);
}
$sign = strtolower(md5($queryStr . "&key=" . self::KEY));
if ($sign == $reqSign) {
return true;
}
}
return false;
}

浙公网安备 33010602011771号