【问题标题】:Shopify C# HMAC SHA256 OAuth ValidationShopify C# HMAC SHA256 OAuth 验证
【发布时间】:2015-11-30 06:09:09
【问题描述】:

我正在尝试在 OAUTH 请求期间验证 Shopify HMAC,但我生成的哈希与请求中提供的哈希不匹配。

我找到了一些其他线程,但它们是 either outdated,因为文档现在指出它使用 GET 请求而不是 POST,或者在 java 中使用 unanswered

我的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();

我猜消息的构建不正确,但我没有运气跟随official documentation

有人可以帮忙吗?

【问题讨论】:

  • 您在不使用密钥的情况下计算 HMAC。该文档指出您应该使用共享密钥生成 HMAC 摘要。试试 cryptographer.Key = keyBytes;在计算哈希之前
  • 试试这个字符串:code=code&shop=shop&state=state&timestamp=timestamp;它对我有用
  • 谢谢帕拉格。我怀疑可能是这种情况,但无论我使用什么参数组合,它仍然不起作用。我已向 Shopify 的开发人员寻求帮助,以便我们看看他们怎么说。
  • @Parag 是正确的。根据文档,您只需删除字段 hmac 和签名并使用剩余变量计算 hmac。将来,如果 shopify 决定在响应中添加另一个变量,则 hmac 计算也应该包括该变量。谢谢段落。

标签: c# oauth shopify sha256 hmac


【解决方案1】:

好的,Shopify 的开发人员回复了我的答案。除了签名和 hmac 之外,您似乎需要按字母顺序散列查询字符串的 整个 内容。我有我自己的参数(rlr),我正在附加以及文档(状态)中未提及的参数。

 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();

现在可以了。

【讨论】:

    【解决方案2】:

    您正在计算 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);
    

    【讨论】:

    • 谢谢,但关键是 HMACSHA256 类的构造函数的一部分。
    • 哦,对不起,我忽略了
    • 你的密码里有非ascii字符吗?
    • 谢谢 Oguz,秘密是一个十六进制字符串,所以没有。
    【解决方案3】:

    使用 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();
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-02
      • 1970-01-01
      • 1970-01-01
      • 2022-06-18
      • 1970-01-01
      • 1970-01-01
      • 2016-01-29
      相关资源
      最近更新 更多