浅谈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 相关文章推荐
4.与数据库的连接
Oct 09 PHP
PHP5 面向对象(学习记录)
Dec 02 PHP
php对二维数组进行排序的简单实例
Dec 19 PHP
destoon实现不同会员组公司名称显示不同的颜色的方法
Aug 22 PHP
php使用递归函数实现数字累加的方法
Mar 16 PHP
php实现的一个简单json rpc框架实例
Mar 30 PHP
PHP输出一个等腰三角形的方法
May 12 PHP
100行PHP代码实现socks5代理服务器
Apr 28 PHP
PHP框架Laravel插件Pagination实现自定义分页
Apr 22 PHP
php 根据自增id创建唯一编号类
Apr 06 PHP
PHP判断json格式是否正确的实现代码
Sep 20 PHP
基于php流程控制语句和循环控制语句(讲解)
Oct 23 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/03/12 PHP
PHP+Ajax验证码验证用户登录
2016/07/20 PHP
php JWT在web端中的使用方法教程
2018/09/06 PHP
用prototype实现的简单小巧的多级联动菜单
2007/03/24 Javascript
ie与ff下的event事件使用介绍
2013/11/25 Javascript
不依赖Flash和任何JS库实现文本复制与剪切附源码下载
2015/10/09 Javascript
JavaScript实现ASC转汉字及汉字转ASC的方法
2016/01/23 Javascript
Javascript类型转换的规则实例解析
2016/02/23 Javascript
动态加载js、css的简单实现代码
2016/05/26 Javascript
使用ajaxfileupload.js实现上传文件功能
2016/08/13 Javascript
学习vue.js中class与style绑定
2016/12/03 Javascript
浅谈node的事件机制
2017/10/09 Javascript
详解基于 Nuxt 的 Vue.js 服务端渲染实践
2017/10/24 Javascript
JavaScript实现删除数组重复元素的5种常用高效算法总结
2018/01/18 Javascript
2019 年编写现代 JavaScript 代码的5个小技巧(小结)
2019/01/15 Javascript
基于AngularJS拖拽插件ngDraggable.js实现拖拽排序功能
2019/04/02 Javascript
layui输入框只允许输入中文且判断长度的例子
2019/09/18 Javascript
Vue 实例事件简单示例
2019/09/19 Javascript
JS控制下拉列表左右选择实例代码
2020/05/08 Javascript
vue element ui validate 主动触发错误提示操作
2020/09/21 Javascript
[20:46]Ti4循环赛第三日VG vs DK
2014/07/12 DOTA
python读取注册表中值的方法
2013/04/08 Python
python判断给定的字符串是否是有效日期的方法
2015/05/13 Python
python正则表达式的使用
2017/06/12 Python
django 通过ajax完成邮箱用户注册、激活账号的方法
2018/04/17 Python
用uWSGI和Nginx部署Flask项目的方法示例
2019/05/05 Python
逼真的HTML5树叶飘落动画
2016/03/01 HTML / CSS
HTML5 图片预加载的示例代码
2020/03/25 HTML / CSS
迪卡侬印度官网:购买所有体育用品
2017/06/24 全球购物
MIKI HOUSE美国官方网上商店:日本领先的婴儿和儿童高级时装品牌
2020/06/21 全球购物
.NET面试10题
2014/02/24 面试题
怀孕辞职信怎么写
2015/02/28 职场文书
考博导师推荐信范文
2015/03/27 职场文书
建党伟业观后感
2015/06/01 职场文书
小学生安全教育心得体会
2016/01/15 职场文书
go语言基础 seek光标位置os包的使用
2021/05/09 Golang