浅谈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 相关文章推荐
discuz程序的PHP加密函数原理分析
Aug 05 PHP
shopex中集成的站长统计功能的代码简单分析
Aug 11 PHP
PHP小教程之实现链表
Jun 09 PHP
跟我学Laravel之视图 & Response
Oct 15 PHP
PHP验证信用卡卡号是否正确函数
May 27 PHP
基于JQuery+PHP编写砸金蛋中奖程序
Sep 08 PHP
Yii实现显示静态页的方法
Apr 25 PHP
php中让人头疼的浮点数运算分析
Oct 10 PHP
PHP截取发动短信内容的方法
Jul 04 PHP
Thinkphp5.0框架的Db操作实例分析【连接、增删改查、链式操作等】
Oct 11 PHP
PHP+ajax实现上传、删除、修改单张图片及后台处理逻辑操作详解
Feb 12 PHP
PHP常用字符串输出方法分析(echo,print,printf及sprintf)
Mar 09 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
php中echo()和print()、require()和include()等易混淆函数的区别
2012/02/22 PHP
php图片的裁剪与缩放生成符合需求的缩略图
2013/01/11 PHP
JavaScript 撑出页面文字换行
2009/06/15 Javascript
Jquery 设置标题的自动翻转
2009/10/03 Javascript
学习ExtJS border布局
2009/10/08 Javascript
JavaScript 常用函数库详解
2009/10/21 Javascript
JS 文件大小判断的实现代码
2010/04/07 Javascript
jquery中的 $("#jb51")与document.getElementById("jb51") 的区别
2011/07/26 Javascript
深入理解JavaScript系列(8) S.O.L.I.D五大原则之里氏替换原则LSP
2012/01/15 Javascript
javascript动态添加样式(行内式/嵌入式/外链式等规则)
2013/06/24 Javascript
JavaScript数组前面插入元素的方法
2015/04/06 Javascript
使用RequireJS优化JavaScript引用代码的方法
2015/07/01 Javascript
JavaScript中SetInterval与setTimeout的用法详解
2015/11/10 Javascript
详解Javascript模板引擎mustache.js
2016/01/20 Javascript
基于jquery实现轮播焦点图插件
2016/03/31 Javascript
jQuery插件 Jqplot图表实例
2016/06/18 Javascript
利用js来实现缩略语列表、文献来源链接和快捷键列表
2016/12/16 Javascript
vue修改对象的属性值后页面不重新渲染的实例
2018/08/09 Javascript
JavaScript 作用域实例分析
2019/10/02 Javascript
使用Python抓取模板之家的CSS模板
2015/03/16 Python
Python合并多个装饰器小技巧
2015/04/28 Python
对python 多个分隔符split 的实例详解
2018/12/20 Python
python线程的几种创建方式详解
2019/08/29 Python
python脚本之一键移动自定格式文件方法实例
2019/09/02 Python
Python数据持久化存储实现方法分析
2019/12/21 Python
使用scrapy ImagesPipeline爬取图片资源的示例代码
2020/09/28 Python
一款纯css3实现的tab选项卡的实列教程
2014/12/11 HTML / CSS
全球性的在线婚纱礼服工厂:27dress.com
2019/03/21 全球购物
日本化妆品植村秀俄罗斯官方网站:Shu Uemura俄罗斯
2020/02/01 全球购物
不同浏览器创建XMLHttpRequest方法有什么不同
2014/11/17 面试题
爱心倡议书范文
2014/05/12 职场文书
2014年科协工作总结
2014/12/09 职场文书
学校办公室主任岗位职责
2015/04/01 职场文书
企业战略合作意向书
2015/05/08 职场文书
zabbix agent2 监控oracle数据库的方法
2021/05/13 Oracle
Java完整实现记事本代码
2022/06/16 Java/Android