Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中验证Paypal webhook签名?_Php_Ssl_Paypal_Openssl_Webhooks - Fatal编程技术网

如何在PHP中验证Paypal webhook签名?

如何在PHP中验证Paypal webhook签名?,php,ssl,paypal,openssl,webhooks,Php,Ssl,Paypal,Openssl,Webhooks,我对SSL和证书不是很了解。我用的是邮局 “看看我能不能让PayPal的网络钩子正常工作 我遇到的问题是,在调用openssl\u verify()并返回结果(0)后,出现以下错误: OpenSSL错误OpenSSL_验证错误:04091068:rsa例程:INT_rsa_验证:错误签名 我试图解决这个问题,但是关于错误和web函数的文档很少甚至没有 我当前的代码如下所示: // get the header post to my php file by PayPal $headers =

我对SSL和证书不是很了解。我用的是邮局 “看看我能不能让PayPal的网络钩子正常工作

我遇到的问题是,在调用
openssl\u verify()
并返回结果(0)后,出现以下错误:

OpenSSL错误OpenSSL_验证错误:04091068:rsa例程:INT_rsa_验证:错误签名

我试图解决这个问题,但是关于错误和web函数的文档很少甚至没有

我当前的代码如下所示:

 // get the header post to my php file by PayPal
 $headers = apache_request_headers();
 // get the body post to me php file by PayPal
 $body = @file_get_contents('php://input');
 $json = json_decode($body);

 // TransmissionId|TransmissionTimeStamp|WebhookId|CRC32 as per PayPal documentation
 $sigString = $headers['Paypal-Transmission-Id'].'|'.$headers['Paypal-Transmission-Time'].'|'.$json->id.'|'.crc32($body);

 // $headers['Paypal-Cert-Url'] contains the "-----BEGIN CERTIFICATE---MIIHmjCCBoKgAwIBAgIQDB8 ... -----END CERTIFICATE-----"
 $pubKey = openssl_pkey_get_public(file_get_contents($headers['Paypal-Cert-Url']));

 // and this is the call to verify that returns result (0)
 $verifyResult = openssl_verify($sigString, base64_decode($headers['Paypal-Transmission-Sig']), $pubKey, 'sha256WithRSAEncryption');
与我使用的参考代码唯一不同的是,我没有使用
openssl\u pkey\u get\u details($pubKey)
,因为除了现有的签名错误之外,我还会得到以下错误:

OpenSSL错误OpenSSL_验证错误:0906D06C:PEM例程:PEM_读取\u bio:无起始行 OpenSSL错误OpenSSL_验证错误:04091068:rsa例程:INT_rsa_验证:错误签名

此外,我还尝试了一种变体,即在标头上不使用
base64\u decode()
,但这将得到相同的返回结果(0),错误为:

OpenSSL错误OpenSSL_验证错误:04091077:rsa例程:INT_rsa_验证:签名长度错误


签名有什么问题?

您可能需要使用以下代码:

$pubKey = openssl_pkey_get_public(file_get_contents($headers['PAYPAL-CERT-URL']));
$details = openssl_pkey_get_details($pubKey);

$verifyResult = openssl_verify($sigString, base64_decode($headers['PAYPAL-TRANSMISSION-SIG']), $details['key'], 'sha256WithRSAEncryption');

if ($verifyResult === 0) {
    throw new Exception('signature incorrect');
} elseif ($verifyResult === -1) {
    throw new Exception('error checking signature');
}

这可能不是您想要的,但是使用开放SSL手动验证签名的替代方法是使用PayPal PHP Restful API

PayPal Restful API公开了一个允许您验证webhook的端点:

提供了一个
VerifyWebhookSignature
类,使调用该端点变得容易


他们还有一个演示如何使用
验证WebHookSignature
类的示例。

公式是
|| |
而不是
| |
。还要注意,Webhook模拟器事件无法验证。

我认为您不应该使用
$json->id
,因为这是事件的id,而不是web hook的id。web钩子ID不是随事件一起发送的-您必须在这里使用常量。我想@Maxime Rainville建议的带有官方SDK的解决方案是一个更好的主意。即使您需要为此执行另一个HTTP调用。