簡體   English   中英

如何驗證 PayPal Webhook 簽名?

[英]How to verify PayPal Webhook signature?

無法驗證從 PayPal 收到的 Webhook。 可用的示例不多,並且集成商沒有足夠的加密知識來完成任務。

遵循的指南是Webhook 通知

不確定代碼片段有什么問題,結果總是錯誤的。

調用notifications/verify-webhook-signature端點也會導致錯誤。

        /// <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時,以下代碼段就足夠了:

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

感謝您在這里提供它,我也在努力尋找一個工作示例!

PS:剛剛在這里發現了官方實現: https://github.com/paypal/PayPal-NET-SDK/blob/master/Source/SDK/Api/WebhookEvent.cs#L156

解決方案是手動序列化 json 有效負載。 像這樣:

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

這是我創建的一個示例,該示例在調用notifications/verify-webhook-signature端點https://gist.github.com/jsdevtom/562b1740164bae8e41f3bc37f28c53 時有效

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM