最近公司对接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 值&notifyUrl=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 SHA1withRSA加密生成签名及验签的更多相关文章

  1. C#通过安全证书生成签名和验签辅助类

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net ...

  2. 使用非对称算法RSA实现加解密和使用签名算法SHA1WithRSA、MD5withRSA生成签名以及验签

    不啰嗦,直接上源码 package com.hudai.platform.manager.util; import java.io.ByteArrayOutputStream; import java ...

  3. erlang的RSA签名与验签

    1.RSA介绍 RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对 其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而 ...

  4. 密码基础知识(2)以RSA为例说明加密、解密、签名、验签

    密码基础知识(1)https://www.cnblogs.com/xdyixia/p/11528572.html 一.RSA加密简介 RSA加密是一种非对称加密.是由一对密钥来进行加解密的过程,分别称 ...

  5. 几个例子理解对称加密与非对称加密、公钥与私钥、签名与验签、数字证书、HTTPS加密方式

    # 原创,转载请留言联系 为什么会出现这么多加密啊,公钥私钥啊,签名啊这些东西呢?说到底还是保证双方通信的安全性与完整性.例如小明发一封表白邮件给小红,他总不希望给别人看见吧.而各种各样的技术就是为了 ...

  6. Delphi支付宝支付【支持SHA1WithRSA(RSA)和SHA256WithRSA(RSA2)签名与验签】

    作者QQ:(648437169) 点击下载➨Delphi支付宝支付             支付宝支付api文档 [Delphi支付宝支付]支持条码支付.扫码支付.交易查询.交易退款.退款查询.交易撤 ...

  7. Delphi RSA签名与验签【支持SHA1WithRSA(RSA1)、SHA256WithRSA(RSA2)和MD5WithRSA签名与验签】

    作者QQ:(648437169) 点击下载➨ RSA签名与验签 [delphi RSA签名与验签]支持3种方式签名与验签(SHA1WithRSA(RSA1).SHA256WithRSA(RSA2)和M ...

  8. RSA后台签名前台验签的应用(前台采用jsrsasign库)

    写在前面 安全测试需要, 为防止后台响应数据返给前台过程中被篡改前台再拿被篡改后的数据进行接下来的操作影响正常业务, 决定采用RSA对响应数据进行签名和验签, 于是有了这篇<RSA后台签名前台验 ...

  9. RSA/RSA2 进行签名和验签

    package com.byttersoft.hibernate.erp.szmy.util; import java.io.ByteArrayInputStream; import java.io. ...

随机推荐

  1. java里 equals和== 区别

    1.java中equals和==的区别 值类型是存储在内存中的堆栈(简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中.2.==操作比较的是两个变量的值是否相等,对于引 ...

  2. CSS 样式初始化

    去除浏览器对html的附加样式,避免不同浏览器之间的样式差异,给前端开发提供统一的样式基础.附加样式: .clearfix - 清除浮动 .wordsBreak - 允许文本在任意位置的换行 .ell ...

  3. Week3——书上的分析

    1.long before=System.currentTimeMills();      long after=System.currentTimeMills(); 该l两句是分别记录了开始过滤和结 ...

  4. 【转】虚拟机安装Ubuntu的上网设置(有线网络和无线网络)

    虚拟机下ubuntu共享方式上网: 一. 有线网络 在有线网络的条件下,vmware的安装非常简单,上网方式几乎不用怎么设置(默认NAT模式)    如果默认情况下不能上网,则按以下步骤尝试: *** ...

  5. 设置 ExpressRoute 和站点到站点并存连接

    配置站点到站点 VPN 和 ExpressRoute 共存连接具有多项优势. 可以将站点到站点 VPN 配置为 ExressRoute 的安全故障转移路径,或者使用站点到站点 VPN 连接到不是通过 ...

  6. [翻译] PNChart

    PNChart https://github.com/kevinzhow/PNChart You can also find swift version at here https://github. ...

  7. 基于NSString处理文件的高级类

    基于NSString处理文件的高级类 我已经把处理文件的类简化到了变态的程度,如果你还有更简洁的方法,请告知我,谢谢! 使用详情: 源码: // // NSString+File.h // Maste ...

  8. 函数的应用 "注册" and "登录"

    登录 自己写 # 注册 registdef regist(): f = open("account", mode="r+", encoding="ut ...

  9. 移动端上下滑动事件之--坑爹的touch.js

    下面的方法,不知道是操作方法不对还是啥.  在 zepto.js 里面加那一段代码不起作用 百度的 touch.js 是可以用的,但是使用方式 和 zepto有点不一样. 解决方案:参照这个链接地址 ...

  10. Alpha 冲刺报告(9/10)

    Alpha 冲刺报告(9/10) 队名:洛基小队 峻雄(组长) 已完成:角色属性功能的测试版 明日计划:准备α版本的ppt 剩余任务:尽量完成角色属性功能 困难:缺乏编程经验,很难自己独立完成编写,只 ...