我试图让PayPal Webhooks与我的PHP应用程序一起使用。 问题是它们通过标头发送的散列算法,我必须使用它来验证请求是否有效。
当我尝试使用它时,我收到此错误:
hash_hmac(): Unknown hashing algorithm: SHA256withRSA
我使用" sha256"尝试了hash_hmac。算法和它工作,所以我认为问题必须与他们希望我使用的那个。
以下是我用来处理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
}
答案 0 :(得分:0)
我认为他们没有使用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签名算法。
答案 1 :(得分:0)
以下是最终有效的代码:
// 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...
我需要解码使用base64_decode()
向我发送的签名PayPal,并且出于某种原因,只有在我使用openssl_pkey_get_details()