浅谈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控制网页过期时间的代码
Sep 28 PHP
php上的memcache和memcached两个pecl库
Mar 29 PHP
常见php数据文件缓存类汇总
Dec 05 PHP
PHP读取配置文件类实例(可读取ini,yaml,xml等)
Jul 28 PHP
PHP中list()函数用法实例简析
Jan 08 PHP
Laravel5.* 打印出执行的sql语句的方法
Jul 24 PHP
PHP下 Mongodb 连接远程数据库的实例代码
Aug 30 PHP
thinkphp5 URL和路由的功能详解与实例
Dec 26 PHP
PHP实现转盘抽奖算法分享
Apr 15 PHP
laravel框架创建授权策略实例分析
Nov 22 PHP
PHP实现抽奖功能实例代码
Jun 30 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打造智能化的柱状图程序,用于报表等
2015/06/19 PHP
详解PHP中的状态模式编程
2015/08/11 PHP
PHP socket 模拟POST 请求实例代码
2016/07/18 PHP
javascript里的条件判断
2007/02/27 Javascript
javascript CSS画图之基础篇
2009/07/29 Javascript
JavaScript中使用指数方法Math.exp()的简介
2015/06/15 Javascript
提高jQuery性能优化的技巧
2015/08/03 Javascript
修改 bootstrap table 默认detailRow样式的实例代码
2017/07/21 Javascript
JS获取子、父、兄节点方法小结
2017/08/14 Javascript
Node.js dgram模块实现UDP通信示例代码
2017/09/26 Javascript
vue 实现通过手机发送短信验证码注册功能
2018/04/19 Javascript
详解.vue文件解析的实现
2018/06/11 Javascript
vue 音乐App QQ音乐搜索列表最新接口跨域设置方法
2018/09/25 Javascript
nuxt踩坑之Vuex状态树的模块方式使用详解
2019/09/06 Javascript
JS插件amCharts实现绘制柱形图默认显示数值功能示例
2019/11/26 Javascript
vue中watch的用法汇总
2020/12/28 Vue.js
pip 错误unused-command-line-argument-hard-error-in-future解决办法
2014/06/01 Python
详解在Python中处理异常的教程
2015/05/24 Python
Python面向对象思想与应用入门教程【类与对象】
2019/04/12 Python
python django model联合主键的例子
2019/08/06 Python
Python使用循环神经网络解决文本分类问题的方法详解
2020/01/16 Python
python Plotly绘图工具的简单使用
2020/03/03 Python
python中常见错误及解决方法
2020/06/21 Python
pytorch 计算ConvTranspose1d输出特征大小方式
2020/06/23 Python
美国运动鞋和运动服零售商:Footaction
2017/04/07 全球购物
Mountain Hardwear官网:攀岩服装和户外装备
2019/09/26 全球购物
学校就业推荐信范文
2014/05/19 职场文书
奉献演讲稿范文
2014/05/21 职场文书
双拥工作宣传标语
2014/06/26 职场文书
领导干部整治奢华浪费之风思想汇报
2014/10/07 职场文书
武夷山导游词
2015/02/03 职场文书
地道战观后感
2015/06/04 职场文书
2015年公司国庆放假通知
2015/07/30 职场文书
CSS3 制作的悬停缩放特效
2021/04/13 HTML / CSS
python 算法题——快乐数的多种解法
2021/05/27 Python
Jupyter Notebook内使用argparse报错的解决方案
2021/06/03 Python