c# - C# 中的 PayPal webhook 签名验证

标签 c# paypal

我有一个从 PayPal 接收 webhook 通知的 C# 应用程序,我想按照 PayPal 文档中的描述验证签名:

https://developer.paypal.com/docs/integration/direct/rest-webhooks-overview/#event-types

文档中的代码片段适用于 Java,而非 C#。我不知道的第一件事是应该以哪种格式附加 CRC32(十进制、十六进制、???)。我已经尝试了几种变体,到目前为止我有以下代码,总是 VerifyData() 返回 false:

string transmissionSig = HttpContext.Request.Headers["PAYPAL-TRANSMISSION-SIG"];
string transmissionId = HttpContext.Request.Headers["PAYPAL-TRANSMISSION-ID"];
string transmissionTime = HttpContext.Request.Headers["PAYPAL-TRANSMISSION-TIME"];
string signatureAlgorithm = HttpContext.Request.Headers["PAYPAL-AUTH-ALGO"]; //signatureAlgorithm == "SHA256withRSA"
string certUrl = HttpContext.Request.Headers["PAYPAL-CERT-URL"]; 

uint crc = calculateCrc32(eventBody);

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

string certData = new System.Net.WebClient().DownloadString(certUrl);

X509Certificate2 cert = new X509Certificate2(getBytes(certData));

RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PublicKey.Key;

byte[] signature = Convert.FromBase64String(transmissionSig);

byte[] expectedBytes = getBytes(expectedSignature);

bool verified = rsa.VerifyData(expectedBytes, CryptoConfig.MapNameToOID("SHA1"), signature);

我做错了什么?

更新

我使用此类进行 CRC 计算:https://github.com/damieng/DamienGKit/blob/master/CSharp/DamienG.Library/Security/Cryptography/Crc32.cs

示例 eventBody(来自 webhook 模拟器):

{"id":"WH-2WR32451HC0233532-67976317FL4543714","create_time":"2014-10-23T17:23:52Z","resource_type":"sale","event_type":"PAYMENT.SALE.COMPLETED","summary":"A successful sale payment was made for $ 0.48 USD","resource":{"id":"80021663DE681814L","create_time":"2014-10-23T17:22:56Z","update_time":"2014-10-23T17:23:04Z","amount":{"total":"0.48","currency":"USD"},"payment_mode":"ECHECK","state":"completed","protection_eligibility":"ELIGIBLE","protection_eligibility_type":"ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE","clearing_time":"2014-10-30T07:00:00Z","parent_payment":"PAY-1PA12106FU478450MKRETS4A","links":[{"href":"https://api.paypal.com/v1/payments/sale/80021663DE681814L","rel":"self","method":"GET"},{"href":"https://api.paypal.com/v1/payments/sale/80021663DE681814L/refund","rel":"refund","method":"POST"},{"href":"https://api.paypal.com/v1/payments/payment/PAY-1PA12106FU478450MKRETS4A","rel":"parent_payment","method":"GET"}]},"links":[{"href":"https://api.paypal.com/v1/notifications/webhooks-events/WH-2WR32451HC0233532-67976317FL4543714","rel":"self","method":"GET"},{"href":"https://api.paypal.com/v1/notifications/webhooks-events/WH-2WR32451HC0233532-67976317FL4543714/resend","rel":"resend","method":"POST"}]}

我正在获取并附加到 expectedSignature 的是 CRC:3561502039

最佳答案

您应该从 header 中获取算法,而不是对其进行硬编码。 SHA256是我认为目前支持的算法。

关于c# - C# 中的 PayPal webhook 签名验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29967922/

相关文章:

c# - 在Microsoft Silverlight中实现可滚动 map (如Google Maps)的最佳方法是什么?

java - 使用 Java 在 Web 应用程序中集成 Paypal

php - Paypal IPN 初学者 - 根本无法使用

javascript - 我如何更改输入以使其像 div 段落一样?

c# - 从 BindingList<T> 派生的类的公共(public)字段/属性不会序列化

c# - 动态合并 2 个类

c# - MediaCapture StartPreviewAsync 失败

C# .Trim 由于某种原因不工作

asp.net - 实现礼品卡

angular - PayPal 可以向其他 PayPal 账户发送付款吗?