如何在 PHP 上将 hash_hmac() 与 "SHA256withRSA" 一起使用?
How to use hash_hmac() with "SHA256withRSA" on PHP?
我正在尝试让 PayPal Webhooks 与我的 PHP 应用程序一起使用。
问题是他们通过 headers 发送的散列算法,我必须使用它来验证请求是否有效。
当我尝试使用它时,出现此错误:
hash_hmac(): Unknown hashing algorithm: SHA256withRSA
我已经尝试 hash_hmac 仅使用 "sha256" 算法并且成功了,所以我认为问题一定出在他们希望我使用的算法上。
这是我用来处理 Webhook 的代码:
$headers = apache_request_headers();
$body = @file_get_contents('php://input');
$json = json_decode($body);
// Concatanate the reqired strings values
$sigString = $headers['PAYPAL-TRANSMISSION-ID'].'|'.$headers['PAYPAL-TRANSMISSION-TIME'].'|'.$json->id.'|'.crc32($body);
// Get the certificate file and read the key
$pub_key = openssl_pkey_get_public(file_get_contents($headers['PAYPAL-CERT-URL']));
$keyData = openssl_pkey_get_details($pub_key);
// check signature
if ($headers['PAYPAL-TRANSMISSION-SIG'] != hash_hmac($headers['PAYPAL-AUTH-ALGO'],$sigString,$keyData['key'])) {
//invalid
}
我认为他们没有使用 HMAC 算法(对称),与他们在文档中所说的相反,而是 RSA(非对称)。所以你应该使用 openssl_verify 来验证签名。也许这会奏效:
//your code here...
// Get the certificate file and read the key
$pubKey = openssl_pkey_get_public(file_get_contents($headers['PAYPAL-CERT-URL']));
$verifyResult = openssl_verify($sigString, $headers['PAYPAL-TRANSMISSION-SIG'], $pubKey, 'sha256WithRSAEncryption');
if ($verifyResult === 0) {
throw new Exception('signature incorrect');
} elseif ($verifyResult === -1) {
throw new Exception('error checking signature');
}
//rest of the code when signature is correct...
PayPal 使用的签名算法名称可能与 PHP 使用的不同。参考openssl_get_md_methods方法获取有效的PHP签名算法。
这是最终有效的代码:
// Get the certificate file and read the key
$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');
}
//rest of the code when signature is correct...
我需要解码 PayPal 使用 base64_decode()
发送给我的签名,出于某种原因,密钥仅在我使用 openssl_pkey_get_details()
时有效
我正在尝试让 PayPal Webhooks 与我的 PHP 应用程序一起使用。 问题是他们通过 headers 发送的散列算法,我必须使用它来验证请求是否有效。
当我尝试使用它时,出现此错误:
hash_hmac(): Unknown hashing algorithm: SHA256withRSA
我已经尝试 hash_hmac 仅使用 "sha256" 算法并且成功了,所以我认为问题一定出在他们希望我使用的算法上。
这是我用来处理 Webhook 的代码:
$headers = apache_request_headers();
$body = @file_get_contents('php://input');
$json = json_decode($body);
// Concatanate the reqired strings values
$sigString = $headers['PAYPAL-TRANSMISSION-ID'].'|'.$headers['PAYPAL-TRANSMISSION-TIME'].'|'.$json->id.'|'.crc32($body);
// Get the certificate file and read the key
$pub_key = openssl_pkey_get_public(file_get_contents($headers['PAYPAL-CERT-URL']));
$keyData = openssl_pkey_get_details($pub_key);
// check signature
if ($headers['PAYPAL-TRANSMISSION-SIG'] != hash_hmac($headers['PAYPAL-AUTH-ALGO'],$sigString,$keyData['key'])) {
//invalid
}
我认为他们没有使用 HMAC 算法(对称),与他们在文档中所说的相反,而是 RSA(非对称)。所以你应该使用 openssl_verify 来验证签名。也许这会奏效:
//your code here...
// Get the certificate file and read the key
$pubKey = openssl_pkey_get_public(file_get_contents($headers['PAYPAL-CERT-URL']));
$verifyResult = openssl_verify($sigString, $headers['PAYPAL-TRANSMISSION-SIG'], $pubKey, 'sha256WithRSAEncryption');
if ($verifyResult === 0) {
throw new Exception('signature incorrect');
} elseif ($verifyResult === -1) {
throw new Exception('error checking signature');
}
//rest of the code when signature is correct...
PayPal 使用的签名算法名称可能与 PHP 使用的不同。参考openssl_get_md_methods方法获取有效的PHP签名算法。
这是最终有效的代码:
// Get the certificate file and read the key
$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');
}
//rest of the code when signature is correct...
我需要解码 PayPal 使用 base64_decode()
发送给我的签名,出于某种原因,密钥仅在我使用 openssl_pkey_get_details()