浅谈PHP SHA1withRSA加密生成签名及验签

2025-05-27 0 83

最近公司对接XX第三方支付平台的代付业务,由于对方公司只有JAVA的demo,所以只能根据文档自己整合PHP的签名加密,网上找过几个方法,踩到各种各样的坑,还好最后算是搞定了,话不多说,代码分享出来。

业务要求:每个签名组装的内容是按字段名的字典顺序升序排序连接的

先组装需要签名的内容:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22
/**

* 拼接需要签名的内容

* 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 值(明文)。

要注意的是,根据业务需要选择,是否在签名内容前拼接 &符。

然后生成秘钥签名

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18
/**

* 秘钥加密

* 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文件)

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46
/**

* 获取公钥

* 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()方法排序。
然后进行验证:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19
/**

* 验证返回的签名是否正确

*

* @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加密签名验签的全部内容了,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对快网idc网站的支持!

原文链接:https://www.cnblogs.com/TuiHo/p/10536895.html

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 浅谈PHP SHA1withRSA加密生成签名及验签 https://www.kuaiidc.com/71613.html

相关文章

发表评论
暂无评论