一.背景
为了增加接口的安全性(防止中间人攻击),现增加签名算法。此算法参考微信支付中的签名算法,由于该签名针对前后端,采用了对称算法,如后续接口供给多家第三方接口使用可采用非对称算法。大致整理文档供后续开发人员使用阅读。
二. 签名生成步骤
①设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
注意如下规则:
◆参数名ASCII码从小到大排序(字典序);
◆如果参数的值为空不参与签名;
◆参数名区分大小写;
◆验证调用返回或主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
②在stringA最后拼接上key(密钥)得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。
样例:假设传送的参数如下:
![](http://image109.360doc.com/DownloadImg/2020/06/2506/193782342_1_20200625061942412)
第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下
stringA = "MEMBER_ID=1&body=test&mch_id=1&order_id=20";
第二步:拼接API密钥(比如key:192006250b4c09247ec02edce69f6a2d)
stringSignTemp = stringA+"&key=192006250b4c09247ec02edce69f6a2d" //注:key为密钥
signValue = md5(stringSignTemp).toUpperCase(); //用MD5加密完后,并且都转为大写
最终打包的数据为(可以就拿这组数据测试):
{"MEMBER_ID":1,"body":"test","mch_id":1,"order_id":20,"sign":4AC10199EFB3D9BF4959DFEA83900ACA}
三. 下面是我整理的JS生成签名的代码,php验证签名的代码
<script src="md5.min.js"></script> //这个网上自己下载 var paramsObj = { order_id: 20, mch_id: 1, body: 'test', MEMBER_ID: 1 };//要传的参数(测试数据) var key = '192006250b4c09247ec02edce69f6a2d'; //密钥 var sign = getSign(paramsObj); //获取签名sign console.log(sign); //输出签名 function getSign(params) { arr.push((i + "=" + params[i])); return paramsStrSort(arr.join(("&"))); function paramsStrSort(paramsStr) { var urlStr = paramsStr.split("&").sort().join("&"); var newUrl = urlStr + '&key=' + key; return md5(newUrl).toUpperCase();
public $key = '192006250b4c09247ec02edce69f6a2d'; //密钥 public function validateSign($params) { $stringA = $this->paramFilter($params); $sign = $this->md5Sign($stringA); if(!isset($params['sign']) || empty($params['sign']) || $params['sign'] != $sign) { * @return array 去掉空值与签名参数后的新签名参数组 function paramFilter($param) { while (list ($key, $val) = each ($param)) { if($key == "sign" || $val == "") continue; else $para_filter[$key] = $param[$key]; return $this->argSort($para_filter); function argSort($param) { return $this->createLinkString($param); * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串 * @return bool|string 拼接完成以后的字符串 function createLinkString($para) { while (list ($key, $val) = each ($para)) { $arg = substr($arg,0,count($arg)-2); if(get_magic_quotes_gpc()){ $arg = stripslashes($arg); $arg = $arg.'&key='.$this->key; * @param $preStr string 需要签名的字符串 function md5Sign($preStr) { return strtoupper(md5($preStr));
|