浅谈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 相关文章推荐
通过html表格发电子邮件
Oct 09 PHP
PHP反转字符串函数strrev()函数的用法
Feb 04 PHP
培养自己的php编码规范
Sep 28 PHP
解决php的“It is not safe to rely on the system’s timezone settings”问题
Oct 08 PHP
php上传图片并压缩的实现方法
Dec 22 PHP
PHP命令行执行整合pathinfo模拟定时任务实例
Aug 12 PHP
PHP基于mssql扩展远程连接MSSQL的简单实现方法
Oct 08 PHP
PHP获取IP地址所在地信息的实例(使用纯真IP数据库qqwry.dat)
Nov 15 PHP
php 如何禁用eval() 函数实例详解
Dec 01 PHP
PHP中Laravel 关联查询返回错误id的解决方法
Apr 01 PHP
为你的 Laravel 验证器加上多验证场景的实现
Apr 07 PHP
PHP后门隐藏的一些技巧总结
Nov 04 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数据库连接
2006/10/09 PHP
php笔记之:有规律大文件的读取与写入的分析
2013/04/26 PHP
php将图片保存入mysql数据库失败的解决方法
2014/12/27 PHP
phpStudy 2016 使用教程详解(支持PHP7)
2017/10/18 PHP
php和vue配合使用技巧和方法
2019/05/09 PHP
Thinkphp5+Redis实现商品秒杀代码实例讲解
2020/12/29 PHP
JS效率个人经验谈(8-15更新),加入range技巧
2007/01/09 Javascript
js中数组(Array)的排序(sort)注意事项说明
2014/01/24 Javascript
无需 Flash 使用 jQuery 复制文字到剪贴板
2016/04/26 Javascript
jQuery ajaxSubmit 实现ajax提交表单局部刷新
2016/07/04 Javascript
select隐藏选中值对应的id,显示其它id的简单实现方法
2016/08/25 Javascript
Bootstrap企业网站实战项目4
2016/10/14 Javascript
Bootstrap和Java分页实例第二篇
2016/12/23 Javascript
vue中使用gojs/jointjs的示例代码
2018/08/24 Javascript
Vue实现用户自定义字段显示数据的方法
2018/08/28 Javascript
微信小程序错误this.setData报错及解决过程
2019/09/18 Javascript
Javascript中的this,bind和that使用实例
2019/12/05 Javascript
python和pygame实现简单俄罗斯方块游戏
2021/02/19 Python
django用户登录和注销的实现方法
2018/07/16 Python
python把数组中的数字每行打印3个并保存在文档中的方法
2018/07/17 Python
Python闭包函数定义与用法分析
2018/07/20 Python
Python3随机漫步生成数据并绘制
2018/08/27 Python
详解Python 字符串相似性的几种度量方法
2019/08/29 Python
Python GUI编程学习笔记之tkinter界面布局显示详解
2020/03/30 Python
pyMySQL SQL语句传参问题,单个参数或多个参数说明
2020/06/06 Python
详解appium自动化测试工具(monitor、uiautomatorviewer)
2021/01/27 Python
德国自然时尚和有机产品购物网站:Waschbär
2019/05/29 全球购物
师范毕业生自荐信
2013/10/17 职场文书
学生意外伤害赔偿协议书
2014/09/17 职场文书
2014年大堂经理工作总结
2014/11/21 职场文书
高中生打架检讨书1000字
2015/02/17 职场文书
年会邀请函的格式及范文五篇
2019/11/02 职场文书
Jupyter notebook 不自动弹出网页的解决方案
2021/05/21 Python
MySql 8.0及对应驱动包匹配的注意点说明
2021/06/23 MySQL
Mysql表数据比较大情况下修改添加字段的方法实例
2022/06/28 MySQL
Win11使用CAD卡顿或者致命错误怎么办?Win11无法正常使用CAD的解决方法
2022/07/23 数码科技