php argsort,MD5数字签名算法:生成签名和验签(附代码)

一.背景

为了增加接口的安全性(防止中间人攻击),现增加签名算法。此算法参考微信支付中的签名算法,由于该签名针对前后端,采用了对称算法,如后续接口供给多家第三方接口使用可采用非对称算法。大致整理文档供后续开发人员使用阅读。

二.  签名生成步骤

①设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。

注意如下规则:

◆参数名ASCII码从小到大排序(字典序);

◆如果参数的值为空不参与签名;

◆参数名区分大小写;

◆验证调用返回或主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。

②在stringA最后拼接上key(密钥)得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。

样例:假设传送的参数如下:

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验证签名的代码

//JS生成签名源码

//这个网上自己下载

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) {

var arr = [];

for (var i in 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();

}

//php服务端验证签名源码

class Sign

{

public $key = '192006250b4c09247ec02edce69f6a2d'; //密钥

/**

* 验签

* @param $params

* @return bool

*/

public function validateSign($params) {

$stringA = $this->paramFilter($params);

$sign = $this->md5Sign($stringA);

if(!isset($params['sign']) || empty($params['sign']) || $params['sign'] != $sign) {

return false;

} else {

return true;

}

}

/**

* 除去数组中的空值和签名参数

* @param $param

* @return array 去掉空值与签名参数后的新签名参数组

*/

function paramFilter($param) {

$para_filter = array();

while (list ($key, $val) = each ($param)) {

if($key == "sign" || $val == "") continue;

else $para_filter[$key] = $param[$key];

}

return $this->argSort($para_filter);

}

/**

* 对数组排序

* @param $param

* @return mixed 排序后的数组

*/

function argSort($param) {

ksort($param);

reset($param);

return $this->createLinkString($param);

}

/**

* 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串

* @param $para

* @return bool|string 拼接完成以后的字符串

*/

function createLinkString($para) {

$arg = "";

while (list ($key, $val) = each ($para)) {

$arg.=$key."=".$val."&";

}

//去掉最后一个&字符

$arg = substr($arg,0,count($arg)-2);

//如果存在转义字符,那么去掉转义

if(get_magic_quotes_gpc()){

$arg = stripslashes($arg);

}

$arg = $arg.'&key='.$this->key;

return $arg;

}

/**

* 生成md5签名字符串

* @param $preStr string 需要签名的字符串

* @return string 签名结果

*/

function md5Sign($preStr) {

return strtoupper(md5($preStr));

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值