C# 中的 PayPal webhook 签名验证 [英] PayPal webhook signature verification in C#

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

问题描述

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

I have a C# application that receives webhook notifications from PayPal and I want to verify the signature as described in PayPal docs:

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

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

The code snippet in the docs is for Java, not C#. The first thing I don't know is in which format the CRC32 should be appended (decimal, hex, ???). I have tried several variants and I have following code so far, always with VerifyData() returning 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

I use this class for CRC calculation: https://github.com/damieng/DamienGKit/blob/master/CSharp/DamienG.Library/Security/Cryptography/Crc32.cs

示例 eventBody(来自网络钩子模拟器):

Example eventBody (from webhook simulator):

{"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

And it's CRC that I'm getting and appending to expectedSignature: 3561502039

推荐答案

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

you should get algorithm from the header in stead of hard-coding it. SHA256 is the currently supported algorithm I think.

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

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