如何创建匹配的HMAC值以验证.NET中的Shopify WebHook?

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)


Dav*_*ood 2

正如您在问题中提到的,您应该在方法中对整个 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)

您可以看到,我们只是获取请求的正文(作为字符串)并将其逐字放入验证方法中。尝试一下,希望你会有更多的运气。