浅谈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 相关文章推荐
在数据量大(超过10万)的情况下
Jan 15 PHP
PHP insert语法详解
Jun 07 PHP
PHP学习之数组的定义和填充
Apr 17 PHP
php实现分页工具类分享
Jan 09 PHP
php数组排序usort、uksort与sort函数用法
Nov 17 PHP
PHP中shuffle数组值随便排序函数用法
Nov 21 PHP
微信公众平台开发关注及取消关注事件的方法
Dec 23 PHP
php实现遍历多维数组的方法
Nov 25 PHP
WordPress中制作导航菜单的PHP核心方法讲解
Dec 11 PHP
PHP+Ajax验证码验证用户登录
Jul 20 PHP
PHP连接MySQL数据库的三种方式实例分析【mysql、mysqli、pdo】
Nov 04 PHP
php array 转json及java 转换 json数据格式操作示例
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中冒号、endif、endwhile、endfor使用介绍
2010/04/28 PHP
YII模块实现绑定二级域名的方法
2014/07/09 PHP
PHP的imageTtfText()函数深入详解
2021/03/03 PHP
Gird事件机制初级读本
2007/03/10 Javascript
jquery1.5.1中根据元素ID获取元素对象的代码
2011/04/02 Javascript
用Javascript实现Windows任务管理器的代码
2012/03/27 Javascript
自己做的模拟模态对话框实现代码
2012/05/23 Javascript
jQuery 计算iframe 窗口大小的方法
2014/05/13 Javascript
js仿黑客帝国字母掉落效果代码分享
2020/11/08 Javascript
javascript实现九宫格相加数值相等
2020/05/28 Javascript
关于List.ToArray()方法的效率测试
2016/09/30 Javascript
Angularjs中ng-repeat-start与ng-repeat-end的用法实例介绍
2016/12/31 Javascript
移动端点击态处理的三种实现方式
2017/01/12 Javascript
实现图片首尾平滑轮播(JS原生方法—节流)
2017/10/17 Javascript
详解基于vue-cli优化的webpack配置
2017/11/06 Javascript
vue实现固定位置显示功能
2019/05/30 Javascript
解决vuex数据异步造成初始化的时候没值报错问题
2019/11/13 Javascript
JavaScript中变量提升机制示例详解
2019/12/27 Javascript
Vue 禁用浏览器的前进后退操作
2020/09/04 Javascript
使用Python实现简单的服务器功能
2017/08/25 Python
代码实例讲解python3的编码问题
2019/07/08 Python
Python Django中间件,中间件函数,全局异常处理操作示例
2019/11/08 Python
德国价格合理的品牌商品购物网站:averdo
2019/03/21 全球购物
Gretna Green中文官网:苏格兰格林小镇
2019/10/16 全球购物
公司庆典邀请函范文
2014/01/13 职场文书
2014年元旦联欢会活动策划方案
2014/02/16 职场文书
师范教师专业大学生职业生涯规划范文
2014/03/02 职场文书
大学军训感言400字
2014/03/11 职场文书
《大海那边》教学反思
2014/04/09 职场文书
教师职业道德事迹材料
2014/08/18 职场文书
2014年度安全工作总结
2014/12/04 职场文书
优秀班集体申报材料
2014/12/25 职场文书
2016秋季幼儿园开学寄语
2015/12/03 职场文书
职场中的你,辞职信写对了吗?
2019/06/26 职场文书
mysql优化之query_cache_limit参数说明
2021/07/01 MySQL
python模块与C和C++动态库相互调用实现过程示例
2021/11/02 Python