ste*_*776 4 .net c# sha256 hmac shopify
我已经设置了一个端点来接收Shopify的webhook请求.
Shopify的请求包括一个HMAC标头,该标头是从共享密钥和请求主体创建的.
我需要在服务器上计算HMAC并将其与请求标头中的值相匹配,以确保请求是可信的.
我似乎无法在.NET中创建适当的机制来创建匹配的HMAC值.
我的算法在这一点如下:
public static string CreateHash(string data)
{
string sharedSecretKey = "MY_KEY";
byte[] keyBytes = Encoding.UTF8.GetBytes(sharedSecretKey);
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
//use the SHA256Managed Class to compute the hash
System.Security.Cryptography.HMACSHA256 hmac = new HMACSHA256(keyBytes);
byte[] hmacBytes = hmac.ComputeHash(dataBytes);
//retun as base64 string. Compared with the signature passed in the header of the post request from Shopify. If they match, the call is verified.
return System.Convert.ToBase64String(hmacBytes);
}
Run Code Online (Sandbox Code Playgroud)
可以在此处找到用于验证其webhook的Shopify文档,但仅包含PHP和Ruby示例.
任何人都可以看到我可能做错了什么?我应该只是将整个JSON请求体作为字符串传递给此方法吗?
小智 7
private static bool Validate(string sharedSecretKey)
{
var data = GetStreamAsText(HttpContext.Current.Request.InputStream, HttpContext.Current.Request.ContentEncoding);
var keyBytes = Encoding.UTF8.GetBytes(sharedSecretKey);
var dataBytes = Encoding.UTF8.GetBytes(data);
//use the SHA256Managed Class to compute the hash
var hmac = new HMACSHA256(keyBytes);
var hmacBytes = hmac.ComputeHash(dataBytes);
//retun as base64 string. Compared with the signature passed in the header of the post request from Shopify. If they match, the call is verified.
var hmacHeader = HttpContext.Current.Request.Headers["x-shopify-hmac-sha256"];
var createSignature = Convert.ToBase64String(hmacBytes);
return hmacHeader == createSignature;
}
private static string GetStreamAsText(Stream stream, Encoding encoding)
{
var bytesToGet = stream.Length;
var input = new byte[bytesToGet];
stream.Read(input, 0, (int)bytesToGet);
stream.Seek(0, SeekOrigin.Begin); // reset stream so that normal ASP.NET processing can read data
var text = encoding.GetString(input);
return text;
}
Run Code Online (Sandbox Code Playgroud)
正如您在问题中提到的,您应该在方法中对整个 json 请求正文进行哈希处理。
我的 .NET 不太好,但下面是 ruby 示例的一部分,它向您展示了该怎么做:
post '/' do
. . .
data = request.body.read
verified = verify_webhook(data, env["HTTP_X_SHOPIFY_HMAC_SHA256"])
. . .
end
Run Code Online (Sandbox Code Playgroud)
您可以看到,我们只是获取请求的正文(作为字符串)并将其逐字放入验证方法中。尝试一下,希望你会有更多的运气。