PayPal在C#中进行webhook签名验证

时间:2015-04-30 12:35:17

标签: c# paypal

我有一个C#应用程序,它接收来自PayPal的webhook通知,我想验证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"}]}

这是我得到的CRC并附加到expectedSignature:3561502039

1 个答案:

答案 0 :(得分:0)

你应该从头部获取算法而不是硬编码。 SHA256是我认为目前支持的算法。