浅谈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 array_map array_multisort 高效处理多维数组排序
Jun 11 PHP
php导出csv格式数据并将数字转换成文本的思路以及代码分享
Jun 05 PHP
PHP开源开发框架ZendFramework使用中常见问题说明及解决方案
Jun 12 PHP
destoon公司主页模板风格的添加方法
Jun 20 PHP
php实现判断访问来路是否为搜索引擎机器人的方法
Apr 15 PHP
WordPress后台中实现图片上传功能的实例讲解
Jan 11 PHP
PHP文件下载实例代码浅析
Aug 17 PHP
PHP实现对xml进行简单的增删改查(CRUD)操作示例
May 19 PHP
PHP实现打包下载文件的方法示例
Oct 07 PHP
PHP连接及操作PostgreSQL数据库的方法详解
Jan 30 PHP
PHP实现的敏感词过滤方法示例
Mar 06 PHP
浅谈laravel orm 中的一对多关系 hasMany
Oct 21 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与XML联手进行网站编程代码实例
2008/07/10 PHP
php实现mysql数据库操作类分享
2014/02/14 PHP
ThinkPHP使用心得分享-分页类Page的用法
2014/05/15 PHP
ThinkPHP打水印及设置水印位置的方法
2016/10/14 PHP
php简单计算年龄的方法(周岁与虚岁)
2016/12/06 PHP
PHPExcel 修改已存在Excel的方法
2018/05/03 PHP
PHP 实现 WebSocket 协议原理与应用详解
2020/04/22 PHP
Javascript的IE和Firefox兼容性汇编(zz)
2007/02/02 Javascript
JavaScript中的事件处理
2008/01/16 Javascript
jquery下操作HTML控件的实现代码
2010/01/12 Javascript
Javascript中arguments对象详解
2014/10/22 Javascript
使用jQuery Mobile框架开发移动端Web App的入门教程
2016/05/17 Javascript
JavaScript微信定位功能实现方法
2016/11/29 Javascript
微信小程序 使用腾讯地图SDK详解及实现步骤
2017/02/28 Javascript
JavaScript正则替换HTML标签功能示例
2017/03/02 Javascript
vue.js $refs和$emit 父子组件交互的方法
2017/12/20 Javascript
详解ES6语法之可迭代协议和迭代器协议
2018/01/13 Javascript
Vue + Elementui实现多标签页共存的方法
2019/06/12 Javascript
微信小程序 如何保持登录状态
2019/08/16 Javascript
vue+webpack dev本地调试全局样式引用失效的解决方案
2019/11/12 Javascript
vue实现评价星星功能
2020/06/30 Javascript
Python 编码Basic Auth使用方法简单实例
2017/05/25 Python
python爬虫的一个常见简单js反爬详解
2019/07/09 Python
对django2.0 关联表的必填on_delete参数的含义解析
2019/08/09 Python
使用Rasterio读取栅格数据的实例讲解
2019/11/26 Python
Python 根据数据模板创建shapefile的实现
2019/11/26 Python
Python %r和%s区别代码实例解析
2020/04/03 Python
小学教师培训感言
2014/02/11 职场文书
小学生寒假家长评语
2014/04/16 职场文书
《黄山奇石》教学反思
2014/04/19 职场文书
法学专业求职信
2014/07/15 职场文书
职工擅自离岗检讨书
2014/09/23 职场文书
英文导游词
2015/02/13 职场文书
教师求职简历自我评价
2015/03/10 职场文书
企业安全生产检查制度
2015/08/06 职场文书
2016年小学生清明节广播稿
2015/12/17 职场文书