【发布时间】:2017-10-08 20:59:20
【问题描述】:
我正在尝试使用 Jayme Davis 的 c# 库 Stripe.net 实现条带 webhook。我已经在条带仪表板中设置了测试端点并生成了秘密。端点被很好地击中,并将使用 StripeEventUtility.ParseEvent 生成 StripeEvent。问题在于使用 ConstructEvent 函数我无法让签名匹配。任何帮助或建议将不胜感激。
isSignaturePresent 返回错误
//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;
}
}
【问题讨论】:
-
如何初始化
json变量? -
我使用 var json = JsonSerializer.SerializeToString(request);
-
所以您正在重新序列化反序列化的请求正文。但是,这不太可能返回与原始请求正文完全相同的字符串。您需要使用 Web 服务器/框架传递的原始请求正文。
-
会试一试,谢谢
-
是的,这是一种享受,谢谢。
标签: c# stripe-payments digital-signature webhooks stripe.net