Im Versuch, eine Stripe Webhook mit der C# -Bibliothek Stripe.net von Jayme Davis zu implementieren. Ich habe den Test-Endpunkt im Stripe-Dashboard eingerichtet und das Geheimnis generiert. Der Endpunkt wird gut getroffen und generiert das StripeEvent mithilfe von StripeEventUtility.ParseEvent. Das Problem liegt in der Verwendung der ConstructEvent-Funktion, die die Übereinstimmung der Signaturen nicht erreichen kann. Jede Hilfe oder Vorschläge wären sehr willkommen.Stripe Webhook Unterschrift fehlgeschlagen - Stripe.net
isSignaturePresent kehrt falsch
//call to create event
stripeEvent = ConstructEvent(json, Request.Headers["Stripe-Signature"],
SecretFromStripeDashBoard);
private StripeEvent ConstructEvent(string json, string
stripeSignatureHeader, string secret, int tolerance = 300)
{
var signatureItems = parseStripeSignature(stripeSignatureHeader);
var signature = computeSignature(secret, signatureItems["t"].FirstOrDefault(), json);
if (!isSignaturePresent(signature, signatureItems["v1"]))
throw new Exception("The signature for the webhook is not present in the Stripe-Signature header.");
//var utcNow = EpochUtcNowOverride ?? DateTime.UtcNow.ConvertDateTimeToEpoch();
//var webhookUtc = Convert.ToInt32(signatureItems["t"].FirstOrDefault());
//if (utcNow - webhookUtc > tolerance)
// throw new Exception("The webhook cannot be processed because the current timestamp is above the allowed tolerance.");
return Mapper<StripeEvent>.MapFromJson(json);
}
private ILookup<string, string> parseStripeSignature(string stripeSignatureHeader)
{
return stripeSignatureHeader.Trim()
.Split(',')
.Select(item => item.Trim().Split('='))
.ToLookup(item => item[0], item => item[1]);
}
private bool isSignaturePresent(string signature, IEnumerable<string> signatures)
{
return signatures.Any(key => secureCompare(key, signature));
}
private string computeSignature(string secret, string timestamp, string payload)
{
var secretBytes = Encoding.UTF8.GetBytes(secret);
var payloadBytes = Encoding.UTF8.GetBytes($"{timestamp}.{payload}");
var cryptographer = new HMACSHA256(secretBytes);
var hash = cryptographer.ComputeHash(payloadBytes);
return BitConverter.ToString(hash).Replace("-", "").ToLower();
}
private bool secureCompare(string a, string b)
{
if (a.Length != b.Length) return false;
var result = 0;
for (var i = 0; i < a.Length; i++)
{
result |= a[i]^b[i];
}
return result == 0;
}
}
Wie initialisierst du die Variable 'json'? – Ywain
ich benutze var json = JsonSerializer.SerializeToString (Anfrage); – stephen
Sie reservieren also den deserialisierten Anfragetext. Es ist jedoch sehr unwahrscheinlich, dass dies genau die gleiche Zeichenfolge wie der ursprüngliche Anfragetext zurückgibt. Sie müssen den rohen Anfragetext verwenden, wie er von Ihrem Webserver/Framework übergeben wurde. – Ywain