如何验证 PayPal Webhook 签名? [英] How to verify PayPal Webhook signature?

查看:38
本文介绍了如何验证 PayPal Webhook 签名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

验证从 PayPal 收到的 Webhook 时遇到问题.可用的示例不多,并且集成商没有足够的加密知识来完成任务.

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.

遵循的指南是Webhook 通知.

不确定代码片段有什么问题,结果总是错误的.

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

调用 notifications/verify-webhook-signature 端点也导致错误.

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;
            }
        }

推荐答案

我可以确认您的实现有效,但是我不确定您使用哪个实现来计算 CRC32 校验和.使用 Crc32.NET 时,以下代码段就足够了:

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:刚刚在这里发现了官方实现:https://github.com/paypal/PayPal-NET-SDK/blob/master/Source/SDK/Api/WebhookEvent.cs#L156

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

这篇关于如何验证 PayPal Webhook 签名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆