分享

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

 西城杂事 2020-06-25

一.背景

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

二.  签名生成步骤

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

注意如下规则:

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

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

◆参数名区分大小写;

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

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

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

第一步:对参数按照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验证签名的代码

  1. //JS生成签名源码
  2. <script src="md5.min.js"></script> //这个网上自己下载
  3. <script>
  4. var paramsObj = { order_id: 20, mch_id: 1, body: 'test', MEMBER_ID: 1 };//要传的参数(测试数据)
  5. var key = '192006250b4c09247ec02edce69f6a2d'; //密钥
  6. var sign = getSign(paramsObj); //获取签名sign
  7. console.log(sign); //输出签名
  8. function getSign(params) {
  9. var arr = [];
  10. for (var i in params) {
  11. arr.push((i + "=" + params[i]));
  12. }
  13. return paramsStrSort(arr.join(("&")));
  14. }
  15. function paramsStrSort(paramsStr) {
  16. var urlStr = paramsStr.split("&").sort().join("&");
  17. var newUrl = urlStr + '&key=' + key;
  18. return md5(newUrl).toUpperCase();
  19. }
  20. </script>
  1. //php服务端验证签名源码
  2. <?php
  3. class Sign
  4. {
  5. public $key = '192006250b4c09247ec02edce69f6a2d'; //密钥
  6. /**
  7. * 验签
  8. * @param $params
  9. * @return bool
  10. */
  11. public function validateSign($params) {
  12. $stringA = $this->paramFilter($params);
  13. $sign = $this->md5Sign($stringA);
  14. if(!isset($params['sign']) || empty($params['sign']) || $params['sign'] != $sign) {
  15. return false;
  16. } else {
  17. return true;
  18. }
  19. }
  20. /**
  21. * 除去数组中的空值和签名参数
  22. * @param $param
  23. * @return array 去掉空值与签名参数后的新签名参数组
  24. */
  25. function paramFilter($param) {
  26. $para_filter = array();
  27. while (list ($key, $val) = each ($param)) {
  28. if($key == "sign" || $val == "") continue;
  29. else $para_filter[$key] = $param[$key];
  30. }
  31. return $this->argSort($para_filter);
  32. }
  33. /**
  34. * 对数组排序
  35. * @param $param
  36. * @return mixed 排序后的数组
  37. */
  38. function argSort($param) {
  39. ksort($param);
  40. reset($param);
  41. return $this->createLinkString($param);
  42. }
  43. /**
  44. * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
  45. * @param $para
  46. * @return bool|string 拼接完成以后的字符串
  47. */
  48. function createLinkString($para) {
  49. $arg = "";
  50. while (list ($key, $val) = each ($para)) {
  51. $arg.=$key."=".$val."&";
  52. }
  53. //去掉最后一个&字符
  54. $arg = substr($arg,0,count($arg)-2);
  55. //如果存在转义字符,那么去掉转义
  56. if(get_magic_quotes_gpc()){
  57. $arg = stripslashes($arg);
  58. }
  59. $arg = $arg.'&key='.$this->key;
  60. return $arg;
  61. }
  62. /**
  63. * 生成md5签名字符串
  64. * @param $preStr string 需要签名的字符串
  65. * @return string 签名结果
  66. */
  67. function md5Sign($preStr) {
  68. return strtoupper(md5($preStr));
  69. }
  70. }

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多