浅谈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 相关文章推荐
E路文章系统PHP
Dec 11 PHP
php判断页面是否是微信打开的示例(微信打开网页)
Apr 25 PHP
php中fgetcsv()函数用法实例
Nov 28 PHP
php强制更新图片缓存的方法
Feb 11 PHP
PHP获取昨天、今天及明天日期的方法
Feb 03 PHP
php获取开始与结束日期之间所有日期的方法
Nov 29 PHP
PHP三种方式实现链式操作详解
Jan 21 PHP
PHP 实现字符串翻转(包含中文汉字)的实现代码
Apr 01 PHP
如何修改yii2.0自带的user表为其它的表
Aug 01 PHP
浅谈laravel框架与thinkPHP框架的区别
Oct 23 PHP
PHP学习记录之常用的魔术常量详解
Dec 12 PHP
PHP http请求超时问题解决方案
Nov 13 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 urlencode()与urldecode()函数字符编码原理详解
2011/12/06 PHP
详解PHP导入导出CSV文件
2014/11/03 PHP
PHP入门教程之操作符与控制结构流程详解
2016/09/09 PHP
php中Redis的应用--消息传递
2017/03/28 PHP
PHP实现字符串翻转功能的方法【递归与循环算法】
2017/11/03 PHP
jquery模拟SELECT下拉框取值效果
2013/10/23 Javascript
Js判断CSS文件加载完毕的具体实现
2014/01/17 Javascript
jQuery无刷新切换主题皮肤实例讲解
2015/10/21 Javascript
JavaScript和JQuery获取DIV值的方法示例
2017/03/07 Javascript
微信小程序 动态绑定数据及动态事件处理
2017/03/14 Javascript
JS查找英文文章中出现频率最高的单词
2017/03/20 Javascript
解决option标签selected="selected"属性失效的问题
2017/11/06 Javascript
vue项目中使用tinymce编辑器的步骤详解
2018/09/11 Javascript
微信小程序列表中item左滑删除功能
2018/11/07 Javascript
详解webpack 最简打包结果分析
2019/02/20 Javascript
详解Vue中组件的缓存
2019/04/20 Javascript
微信浏览器下拉黑边解决方案 wScroollFix
2020/01/21 Javascript
javascript-hashchange事件和历史状态管理实例分析
2020/04/18 Javascript
详谈vue中router-link和传统a链接的区别
2020/07/22 Javascript
python使用装饰器和线程限制函数执行时间的方法
2015/04/18 Python
举例讲解Python中的迭代器、生成器与列表解析用法
2016/03/20 Python
Python模块结构与布局操作方法实例分析
2017/07/24 Python
python操作excel的方法(xlsxwriter包的使用)
2018/06/11 Python
Python并发:多线程与多进程的详解
2019/01/24 Python
python Elasticsearch索引建立和数据的上传详解
2019/08/04 Python
python查看数据类型的方法
2019/10/12 Python
浅谈pymysql查询语句中带有in时传递参数的问题
2020/06/05 Python
python判断是空的实例分享
2020/07/06 Python
Myprotein法国官网:欧洲第一运动营养品牌
2019/03/26 全球购物
解释下列WebService名词:WSDL、SOAP、UDDI
2012/06/22 面试题
运动会入场词100字
2014/02/06 职场文书
竞选班长演讲稿400字
2014/08/22 职场文书
行政秘书工作自我鉴定
2014/09/15 职场文书
2014年煤矿安全工作总结
2014/12/04 职场文书
python 统计代码耗时的几种方法分享
2021/04/02 Python
Win11怎么添加用户?Win11添加用户账户的方法
2022/07/15 数码科技