浅谈PHP SHA1withRSA加密生成签名及验签


Posted in PHP onMarch 18, 2019

最近公司对接XX第三方支付平台的代付业务,由于对方公司只有JAVA的demo,所以只能根据文档自己整合PHP的签名加密,网上找过几个方法,踩到各种各样的坑,还好最后算是搞定了,话不多说,代码分享出来。

业务要求:每个签名组装的内容是按字段名的字典顺序升序排序连接的

先组装需要签名的内容:

/**
   * 拼接需要签名的内容
   * Author: Tao.
   *
   * @param array $data 需签名的字段内容
   * 
   * @return string
   */   
  public static function getSign($data)
  {
    foreach ($data as $k => $v) {
      $Parameters[$k] = $v;
    }
    //按字典序排序参数
    ksort($Parameters);
    $sign = '';
    foreach ($Parameters as $k => $v) {
      $sign .= $k . "=" . $v . "&";
    }
    $sign = '&' . rtrim($sign, '&');
    return $sign;
  }

签名字符串如下示例:
&amount=amount 值&ccy=ccy 值 &merchantId=merchantId 值¬ifyUrl=notifyUrl 值&orderId=orderId 值 &payeeAcctNo=payeeAcctNo 值(明文)。

要注意的是,根据业务需要选择,是否在签名内容前拼接 &符。

然后生成秘钥签名:

/**
   * 秘钥加密
   * Author: Tao.
   *
   * @param string $data 之前生成好的需加密内容
   * @param $key 私钥证书位置(.pfx文件)
   * @param string $pwd 证书密码
   *
   * @return string
   */
  public static function SHA1withRSA($data, $key,$pwd)
  {
    openssl_pkcs12_read(file_get_contents($key), $certs, $pwd); 
    if (!$certs) return;
    $signature = '';
    openssl_sign($data, $signature, $certs['pkey']);
    return bin2hex($signature); 
  }

于第三方公司要求转换使用16进制,可根据需求选择bin2hex()或base64_encode()。

这里要注意的是,根据业务需要,签名后的内容是否要求大小写敏感。

签名后的内容应该是小写的,可以使用strtoupper()转换成大写。

以上就是给大家整理好的私钥加密方法。

但此业务中另要求将银行卡号需要进行RSA公钥加密
以下是获取公钥的方法:
此处是获取对方平台证书的公钥(.cer文件)

/**
   * 获取公钥
   * Author: Tao.
   *
   * @param $path //公钥证书位置 (.cer文件)
   *
   * @return mixed
   * @throws \Exception
   */
  public static function loadCert($path)
  {
    $file = file_get_contents($path);
    if (!$file) {
      throw new \Exception('loadx509Cert::file_get_contents ERROR');
    }

    $cert = chunk_split(base64_encode($file), 64, "\n");
    $cert = "-----BEGIN CERTIFICATE-----\n" . $cert . "-----END CERTIFICATE-----\n";

    $res = openssl_pkey_get_public($cert);
    $detail = openssl_pkey_get_details($res);
    openssl_free_key($res);

    if (!$detail) {
      throw new \Exception('loadX509Cert::openssl_pkey_get_details ERROR');
    }
    return $detail['key'];
  }

  /**
   * 公钥加密
   * Author: Tao.
   * 
   * @param $pubPath //公钥证书位置 (.cer文件)
   * @param string $bankCode //银行卡号
   * 
   * @return string
   */
  public static function rsa_encode($bankCode,$pubPath)
  {
    $pubkey = self::loadCert($pubPath);
    $encrypt_data = '';
    openssl_public_encrypt($bankCode, $encrypt_data, $pubkey);
    $encrypt_data = base64_encode($encrypt_data);
    return $encrypt_data;
  }

你要问我为什么私钥是bin2hex(),公钥换了base64_encode()。我也不知道为什么,问过说是16位,但是请求签名一直失败,换了64成功了。对方说文档太老了,忘记了。。根据需要选择吧
最后回调结果验签

首先先将回调数据中组装签名字段的内容取出来,按上面的getSign()方法排序。
然后进行验证:

/**
   * 验证返回的签名是否正确
   *
   * @param string $data 要验证的签名原文
   * @param string $signature 签名内容
   *@param $pubPath 公钥证书位置 (.cer文件)
   *
   * @return bool
   */
  public static function verifyRespondSign($data, $signature,$pubPath)
  {
    $keys = self::loadCert($pubPath);
    $signature = hex2bin($signature);
    $ok = openssl_verify($data, $signature, $keys);
    if ($ok == 1) {
      return true;
    }
    return false;
  }

以上所述是小编给大家介绍的PHP SHA1withRSA加密、签名及验签的全部内容了,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

PHP 相关文章推荐
Smarty+QUICKFORM小小演示
Feb 25 PHP
教你如何快捷的使用cmd访问mysql小技巧
May 26 PHP
php从csv文件读取数据并输出到网页的方法
Mar 14 PHP
PHP递归遍历指定目录的文件并统计文件数量的方法
Mar 24 PHP
PHP生成json和xml类型接口数据格式
May 17 PHP
PHP实现过滤掉非汉字字符只保留中文字符
Jun 04 PHP
php实现curl模拟ftp上传的方法
Jul 29 PHP
php制作简单模版引擎
Apr 07 PHP
PHP实现图片的等比缩放和Logo水印功能示例
May 04 PHP
ajax+php实现无刷新验证手机号的实例
Dec 22 PHP
浅谈PHP匿名函数和闭包
Mar 08 PHP
php将xml转化对象的实例详解
Nov 17 PHP
PHP自动生成缩略图函数的源码示例
Mar 18 #PHP
PHP添加文字水印或图片水印的水印类完整源代码与使用示例
Mar 18 #PHP
PHP实现对数字分隔加千分号的方法
Mar 18 #PHP
PHP生成指定范围内的N个不重复的随机数
Mar 18 #PHP
PHP中十六进制颜色与RGB颜色值互转的方法
Mar 18 #PHP
PHP将整数数字转换为罗马数字实例分享
Mar 17 #PHP
PHP标准库(PHP SPL)详解
Mar 16 #PHP
You might like
晶体管单管来复再生式收音机
2021/03/02 无线电
关于ob_get_contents(),ob_end_clean(),ob_start(),的具体用法详解
2013/06/24 PHP
异步加载技术实现当滚动条到最底部的瀑布流效果
2014/09/16 PHP
memcache一致性hash的php实现方法
2015/03/05 PHP
PHP使用正则表达式获取微博中的话题和对象名
2015/07/18 PHP
非常漂亮的JS代码经典广告
2007/10/21 Javascript
jquery maxlength使用说明
2011/09/09 Javascript
当jQuery遭遇CoffeeScript的时候 使用分享
2011/09/17 Javascript
ExtJS4如何给同一个formpanel不同的url
2014/05/02 Javascript
动态生成的DOM不会触发onclick事件的原因及解决方法
2016/08/06 Javascript
利用Jquery队列实现根据输入数量显示的动画
2016/09/01 Javascript
Angular中使用ui router实现系统权限控制及开发遇到问题
2016/09/23 Javascript
jquery.uploadifive插件怎么解决上传限制图片或文件大小问题
2017/05/08 jQuery
js动态引入的四种方法
2018/05/05 Javascript
通过循环优化 JavaScript 程序
2019/06/24 Javascript
Weex开发之WEEX-EROS开发踩坑(小结)
2019/10/16 Javascript
JS数组方法concat()用法实例分析
2020/01/18 Javascript
js实现小星星游戏
2020/03/23 Javascript
vscode中Vue别名路径提示的实现
2020/07/31 Javascript
JavaScript函数柯里化实现原理及过程
2020/12/02 Javascript
[00:32]2018DOTA2亚洲邀请赛出场——VP
2018/04/04 DOTA
[52:06]FNATIC vs NIP 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/19 DOTA
Python检测字符串中是否包含某字符集合中的字符
2015/05/21 Python
使用python读取csv文件快速插入数据库的实例
2018/06/21 Python
pandas处理csv文件的方法步骤
2020/10/16 Python
关于python scrapy中添加cookie踩坑记录
2020/11/17 Python
详解移动端html5页面长按实现高亮全选文本内容的兼容解决方案
2016/12/03 HTML / CSS
GAP美国官网:美国休闲时尚品牌
2016/08/26 全球购物
ghd法国官方网站:英国最受欢迎的美发工具品牌
2019/04/18 全球购物
材料加工工程求职信
2014/02/19 职场文书
领导班子四风查摆对照检查材料思想汇报
2014/10/05 职场文书
给老婆的检讨书1000字
2015/01/01 职场文书
写给同事的离职感言
2015/08/04 职场文书
python基础之匿名函数详解
2021/04/21 Python
Python网络编程之ZeroMQ知识总结
2021/04/25 Python
MySQL 发生同步延迟时Seconds_Behind_Master还为0的原因
2021/06/21 MySQL