浅谈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 相关文章推荐
中篇:安装及配置PHP
Dec 13 PHP
php实现自动获取生成文章主题关键词功能的深入分析
Jun 03 PHP
php出现web系统多域名登录失败的解决方法
Sep 30 PHP
php常用hash加密函数
Nov 22 PHP
ThinkPHP打水印及设置水印位置的方法
Oct 14 PHP
PHP使用curl函数发送Post请求的注意事项
Nov 26 PHP
php一个文件搞定微信jssdk配置
Dec 12 PHP
PHP中单例模式的使用场景与使用方法讲解
Mar 18 PHP
wordpress自定义标签云与随机获取标签的方法详解
Mar 22 PHP
YII2框架使用控制台命令的方法分析
Mar 18 PHP
PHP数组基本用法与知识点总结
Jun 02 PHP
php实现记事本案例
Oct 20 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如何将日志写进syslog
2013/06/28 PHP
详解PHP数组赋值方法
2015/11/07 PHP
PHP仿微信发红包领红包效果
2016/10/30 PHP
jQuery操作 input type=checkbox的实现代码
2012/06/14 Javascript
基于JavaScript 下namespace 功能的简单分析
2013/07/05 Javascript
JavaScript实现16进制颜色值转RGB的方法
2015/02/09 Javascript
体验jQuery和AngularJS的不同点及AngularJS的迷人之处
2016/02/02 Javascript
详解Javacript和AngularJS中的Promises
2016/02/09 Javascript
jQuery之简单的表单验证实例
2016/07/07 Javascript
js鼠标跟随运动效果
2017/03/11 Javascript
js实现旋转木马效果
2017/03/17 Javascript
详解angularJS+Ionic移动端图片上传的解决办法
2017/09/13 Javascript
vue实现消息的无缝滚动效果的示例代码
2017/12/05 Javascript
使用vue-cli编写vue插件的方法
2018/02/26 Javascript
利用Webpack实现小程序多项目管理的方法
2019/02/25 Javascript
Python的字典和列表的使用中一些需要注意的地方
2015/04/24 Python
浅谈终端直接执行py文件,不需要python命令
2017/01/23 Python
python和ruby,我选谁?
2017/09/13 Python
Python回文字符串及回文数字判定功能示例
2018/03/20 Python
Python从ZabbixAPI获取信息及实现Zabbix-API 监控的方法
2018/09/17 Python
Python实现的简单线性回归算法实例分析
2018/12/26 Python
Python实现图片转字符画的代码实例
2019/02/22 Python
Python+PyQT5的子线程更新UI界面的实例
2019/06/14 Python
python实发邮件实例详解
2019/11/11 Python
python模块和包的应用BASE_PATH使用解析
2019/12/14 Python
PyCharm+PyQt5+QtDesigner配置详解
2020/08/12 Python
python+excel接口自动化获取token并作为请求参数进行传参操作
2020/11/10 Python
CSS3使用transition实现的鼠标悬停淡入淡出
2015/01/09 HTML / CSS
经典c++面试题三
2015/07/08 面试题
设计部经理的岗位职责
2013/11/16 职场文书
师范生的个人求职信范文
2014/01/04 职场文书
翻译学院毕业生自荐书
2014/02/02 职场文书
关于环保的建议书
2014/05/12 职场文书
在职证明书范本(2014新版)
2014/09/25 职场文书
工作检讨书范文
2015/01/23 职场文书
Nginx反向代理多个服务器的实现方法
2021/03/31 Servers