Shopify C# HMAC SHA256 OAuth Validation

本文关键字:OAuth Validation SHA256 HMAC Shopify | 更新日期: 2023-09-27 18:25:04

我试图在OAUTH请求期间验证Shopify HMAC,但我生成的哈希与作为请求一部分提供的哈希不匹配。

我发现了一些其他线程,但它们要么已经过时了,正如文档现在所说的那样,它使用GET请求而不是POST,要么在java中没有得到响应。

我的C#代码如下:

string key = "mysecretkey";
string message = string.Format("shop={0}&timestamp={1}", shop, timestamp);
System.Text.ASCIIEncoding encoding = new ASCIIEncoding();
byte[] keyBytes = encoding.GetBytes(key);
byte[] messageBytes = encoding.GetBytes(message);
System.Security.Cryptography.HMACSHA256 cryptographer = new System.Security.Cryptography.HMACSHA256(keyBytes);
byte[] bytes = cryptographer.ComputeHash(messageBytes);
string digest = BitConverter.ToString(bytes).Replace("-", "");
bool valid = digest == hmac.ToUpper();

我猜这个消息是错误构建的,但我遵循了官方文档,运气不好。

有人能帮忙吗?

Shopify C# HMAC SHA256 OAuth Validation

好吧,Shopify的开发人员给了我答案。似乎您需要按字母顺序对querystring的整个内容进行散列,签名和hmac除外。我有自己的参数(rlr),我正在附加,还有一个在文档(state)中没有提到的参数。

 string message = "";// "code=7af66fd73427a1634cee3103297230b8&rlr=9DFD5EA9-7747-4142-97D9-2D44BBA442F1&shop=appswiz.myshopify.com&state=fa992b8f-762e-4813-b707-6044e71ad3b5&timestamp=1448856806";
        message = "code=xxxxxxxx";
        message += "&rlr=xxxxx";
        message += "&shop=xxx.myshopify.com";
        message += "&state=xxxxxxxx";
        message += "&timestamp=1449111190";
        hmac = "xxxxxxx";
        System.Text.ASCIIEncoding encoding = new ASCIIEncoding();
        byte[] keyBytes = encoding.GetBytes(key);
        byte[] messageBytes = encoding.GetBytes(message);
        System.Security.Cryptography.HMACSHA256 cryptographer = new System.Security.Cryptography.HMACSHA256(keyBytes);
        byte[] bytes = cryptographer.ComputeHash(messageBytes);
        string digest = BitConverter.ToString(bytes).Replace("-", "");
        return digest == hmac.ToUpper();

这现在起作用了。

您在不使用密钥的情况下计算HMAC。

文档指出,您应该使用共享密钥生成HMAC摘要。无论如何,没有密钥的HMAC值的含义是什么?如果shopify没有使用您和他们之间的预共享密钥来计算HMAC,任何人都可以模仿shopify服务器。

以下代码块来自文档:

digest = OpenSSL::Digest.new('sha256')
secret = "hush"
message = "shop=some-shop.myshopify.com&timestamp=1337178173"
digest = OpenSSL::HMAC.hexdigest(digest, secret, message)
digest == "2cb1a277650a659f1b11e92a4a64275b128e037f2c3390e3c8fd2d8721dac9e2"

因此,在计算哈希之前,请尝试cryptographer.Key = keyBytes;

byte[] keyBytes = encoding.GetBytes(key);
byte[] messageBytes = encoding.GetBytes(message);
System.Security.Cryptography.HMACSHA256 cryptographer = new System.Security.Cryptography.HMACSHA256(keyBytes);
cryptographer.Key = keyBytes;
byte[] bytes = cryptographer.ComputeHash(messageBytes);

使用Guy Lowe的答案,我最近得到了这个工作:

    public bool ValidateShopifyHmac(string hmacHeader, string localData, string apiSecret) {
        var ascii = new ASCIIEncoding();
        var secretBytes = ascii.GetBytes(apiSecret);
        var cryptographer = new System.Security.Cryptography.HMACSHA256(secretBytes);
        var messageBytes = ascii.GetBytes(localData);
        var hashedMessage = cryptographer.ComputeHash(messageBytes);
        var digest = BitConverter.ToString(hashedMessage).Replace("-", "");
        return digest == hmacHeader.ToUpper();
    }