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; }