浅谈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 相关文章推荐
文章推荐系统(二)
Oct 09 PHP
php 采集书并合成txt格式的实现代码
Mar 01 PHP
PHP 加密与解密的斗争
Apr 17 PHP
php 字符过滤类,用于过滤各类用户输入的数据
May 27 PHP
php中数字0和空值的区别分析
Jun 05 PHP
php生成静态html页面的方法(2种方法)
Sep 14 PHP
Symfony2学习笔记之插件格式分析
Mar 17 PHP
php短信接口代码
May 13 PHP
PHP实现支持加盐的图片加密解密
Sep 09 PHP
PHP基于DOMDocument解析和生成xml的方法分析
Jul 17 PHP
CakePHP框架Model函数定义方法示例
Aug 04 PHP
PHP-FPM和Nginx的通信机制详解
Feb 01 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 反射机制实现动态代理的代码
2008/10/22 PHP
PHP下编码转换函数mb_convert_encoding与iconv的使用说明
2009/12/16 PHP
php中hashtable实现示例分享
2014/02/13 PHP
php导入excel文件到mysql数据库的方法
2015/01/14 PHP
php无限分类使用concat如何实现
2015/11/05 PHP
php+jQuery+Ajax实现点赞效果的方法(附源码下载)
2020/07/21 PHP
收集的10个免费的jQuery相册
2011/02/26 Javascript
getJSON调用后台json数据时函数被调用两次的原因猜想
2013/09/29 Javascript
js 上下左右键控制焦点(示例代码)
2013/12/14 Javascript
如何编写高质量JS代码
2014/12/28 Javascript
深入理解JavaScript系列(26):设计模式之构造函数模式详解
2015/03/03 Javascript
讲解JavaScript的Backbone.js框架的MVC结构设计理念
2016/02/14 Javascript
javascript 中设置window.location.href跳转无效问题解决办法
2017/02/09 Javascript
简单实现js点击展开二级菜单功能
2017/05/16 Javascript
封装运动框架实战左右与上下滑动的焦点轮播图(实例)
2017/10/17 Javascript
JS数组方法slice()用法实例分析
2020/01/18 Javascript
Vue项目配置跨域访问和代理proxy设置方式
2020/09/08 Javascript
Python 正则表达式(转义问题)
2014/12/15 Python
Python文本统计功能之西游记用字统计操作示例
2018/05/07 Python
python 监听salt job状态,并任务数据推送到redis中的方法
2019/01/14 Python
numpy库与pandas库axis=0,axis= 1轴的用法详解
2019/05/27 Python
VSCode中自动为Python文件添加头部注释
2019/11/14 Python
Python多线程获取返回值代码实例
2020/02/17 Python
python 发送邮件的四种方法汇总
2020/12/02 Python
档案接收函范文
2014/01/10 职场文书
教学器材管理制度
2014/01/26 职场文书
表决心的诗句大全
2014/03/11 职场文书
美术专业自荐信
2014/07/07 职场文书
工厂门卫的岗位职责
2014/07/27 职场文书
2014年乡镇工会工作总结
2014/12/02 职场文书
2015年大学生工作总结
2015/04/21 职场文书
一定要知道的 25 个 Vue 技巧
2021/11/02 Vue.js
Go语言基础函数基本用法及示例详解
2021/11/17 Golang
工厂无线对讲系统解决方案
2022/02/18 无线电
【海涛dota解说】一房久违的影魔魂守二连发
2022/04/01 DOTA
Win10 Anaconda安装python-pcl
2022/04/29 Servers