简体   繁体   中英

How to verify PayPal Webhook signature?

Having trouble validating the Webhook received from PayPal. Not many examples are available and not enough knowledge about encryption is possessed by the integrator to accomplish the task.

The guide being followed is Webhook notifications .

Not sure what is wrong with the code snippet, the result is always false.

Calling notifications/verify-webhook-signature endpoint is also resulting in false.

        /// <summary>Verify PayPal Webhook Signature</summary>
        /// <param name="webhookId">0YF54686R9851380C</param>
        /// <param name="transmissionId">785bc690-901d-11ea-8fc5-17f05150a6df</param>
        /// <param name="transmissionTime">2020-05-07T04:44:33Z</param>
        /// <param name="certUrl">https://api.sandbox.paypal.com/v1/notifications/certs/CERT-.....</param>
        /// <param name="transmissionSignature"></param>
        /// <param name="webHookEvent">"{\"id\":\"WH-5P8216093E7920426-60J97470GW748563B\",\"create_time\":\"2020-05-07T11:43:48.000Z\",....</param>
        private static void VerifyWebhookSignature(string webhookId, string transmissionId, string transmissionTime,
            string certUrl, string transmissionSignature, string webHookEvent)
        {
            Crc32 crc32 = new Crc32();
            String hash = string.Empty;

            var arrayOfBytes = Encoding.UTF8.GetBytes(webHookEvent);
            foreach (byte b in crc32.ComputeHash(arrayOfBytes)) hash += b.ToString("x2").ToLower();

            string expectedSignature = String.Format("{0}|{1}|{2}|{3}", transmissionId,
                transmissionTime, webhookId, hash);

            string certData = new System.Net.WebClient().DownloadString(certUrl);
            X509Certificate2 cert = new X509Certificate2(Encoding.UTF8.GetBytes(certData));

            try
            {
                byte[] signature = Convert.FromBase64String(transmissionSignature);
                byte[] expectedBytes = Encoding.UTF8.GetBytes(expectedSignature);

                using (RSA rsa = cert.GetRSAPublicKey())
                {
                    var verified = rsa.VerifyData(
                        expectedBytes,
                        signature,
                        HashAlgorithmName.SHA256,
                        RSASignaturePadding.Pkcs1);

                    Console.WriteLine($"Verified: {verified}");
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

I can confirm that your implementation works, however I'm not sure which implementation you are using to calculate the CRC32 checksum. When using Crc32.NET the following snippet is sufficient:

var arrayOfBytes = Encoding.UTF8.GetBytes(webHookEvent);
string hash = Crc32Algorithm.Compute(arrayOfBytes).ToString();

Thanks for providing it here, I was struggling as well to find a working example!

PS: just discovered the official implementation here: https://github.com/paypal/PayPal-NET-SDK/blob/master/Source/SDK/Api/WebhookEvent.cs#L156

The solution was to manually serialize the json payload. Like so:

        var paypalVerifyRequestJsonString = $@"{{
            ""transmission_id"": ""{headerDictionary["PAYPAL-TRANSMISSION-ID"][0]}"",
            ""transmission_time"": ""{headerDictionary["PAYPAL-TRANSMISSION-TIME"][0]}"",
            ""cert_url"": ""{headerDictionary["PAYPAL-CERT-URL"][0]}"",
            ""auth_algo"": ""{headerDictionary["PAYPAL-AUTH-ALGO"][0]}"",
            ""transmission_sig"": ""{headerDictionary["PAYPAL-TRANSMISSION-SIG"][0]}"",
            ""webhook_id"": ""<get from paypal developer dashboard>"",
            ""webhook_event"": {JsonConvert.DeserializeObject(json)}
            }}";

Here is an example I created which works when calling the notifications/verify-webhook-signature endpoint https://gist.github.com/jsdevtom/562b1740164bae8e41f3bc37f28c5328

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM