【问题标题】:Try To Code HMAC-SHA256 using C#.Net尝试使用 C#.Net 编写 HMAC-SHA256
【发布时间】:2014-02-02 04:26:13
【问题描述】:

我尝试将 HMAC-SHA256 算法编码为函数

HMAC (K,m) = H((K ⊕ opad) ∥ H((K ⊕ ipad) ∥ m))

在哪里

  • H 是一个加密哈希函数,
  • K 是一个秘密密钥,在散列函数的输入块大小或原始密钥的散列(如果它长于该块大小)的右侧用额外的零填充,
  • m是要认证的消息,
  • ∥ 表示连接,
  • ⊕表示异或(XOR),
  • opad 是外部填充(0x5c5c5c…5c5c,一个块长的十六进制常量),
  • ipad 是内部填充(0x363636…3636,一个块长的十六进制常量)。

这是我的代码

public static string MyHMACHash(string key , string message)
{
    Encoding encoding = Encoding.UTF8;
    //var md = System.Security.Cryptography.MD5CryptoServiceProvider.Create();
    SHA256 hash = SHA256Managed.Create();
    byte[] trans_5C = new byte[32];
    byte[] trans_36 = new byte[32];

    byte[] b_key = encoding.GetBytes(key);
    // TODO: also check if key is to short
    if (b_key.Length > 32)
        b_key = hash.ComputeHash(b_key);

    for (int i = 0; i < 32; i++)
    {
        trans_5C[i] = 92;
        trans_36[i] = 54;
        if (i < key.Length)
        {
            trans_5C[i] ^= b_key[i];
            trans_36[i] ^= b_key[i];
        }
    }

    byte[] inner = hash.ComputeHash(trans_36.Concat(encoding.GetBytes(message)).ToArray());
    var Fhash = hash.ComputeHash(trans_5C.Concat(inner).ToArray());

    StringBuilder sb = new StringBuilder();
    foreach (byte b in Fhash)
        sb.Append(b.ToString("x2"));

    string result = sb.ToString(); // = 9036a1a3f654aefeab426e9f7e17288e
    return result;
}

但是当我尝试测试此代码时,结果不符合标准互联网网站上的标准 HMAC-SHA256 散列

【问题讨论】:

  • 有什么原因你不使用内置的HMACSHA256 Class
  • 因为我研究过尝试对 KEY 进行一些更改并在我的结果和标准结果之间进行比较,所以我想确保,原则上,我的代码在 make 之前返回结果作为标准我的改变

标签: c# hmacsha1


【解决方案1】:

这是带有自定义 HMAC 生成的修改版本。主要要考虑的是K中提到的Input Block Size,是哈希算法的块大小;未返回散列字节长度。对于 SHA256,块大小为 64 字节。我相信您使用的是 32 字节块大小。您可以在此处找到不同的块大小参考:http://en.wikipedia.org/wiki/Secure_Hash_Algorithm

public static string MyHMACHash(string key, string message)
{
    Encoding encoding = Encoding.UTF8;

    //Reference http://en.wikipedia.org/wiki/Secure_Hash_Algorithm
    //SHA256 block size is 512 bits => 64 bytes.
    const int HashBlockSize = 64;

    var keyBytes = encoding.GetBytes(key);
    var opadKeySet = new byte[HashBlockSize];
    var ipadKeySet = new byte[HashBlockSize];


    if (keyBytes.Length > HashBlockSize)
    {
        keyBytes = GetHash(keyBytes);
    }

    // This condition is independent of previous
    // condition. If previous was true
    // we still need to execute this to make keyBytes same length
    // as blocksize with 0 padded if its less than block size
    if (keyBytes.Length < HashBlockSize)
    {
        var newKeyBytes = new byte[HashBlockSize];
        keyBytes.CopyTo(newKeyBytes, 0);
        keyBytes = newKeyBytes;
    }


    for (int i = 0; i < keyBytes.Length; i++)
    {
        opadKeySet[i] = (byte)(keyBytes[i] ^ 0x5C);
        ipadKeySet[i] = (byte)(keyBytes[i] ^ 0x36);
    }

    var hash = GetHash(ByteConcat(opadKeySet, 
        GetHash(ByteConcat(ipadKeySet, encoding.GetBytes(message)))));

    // Convert to standard hex string 
    return hash.Select<byte, string>(a => a.ToString("x2"))
                .Aggregate<string>((a, b) => string.Format("{0}{1}", a, b));            
}

public static byte[] GetHash(byte[] bytes)
{
    using (var hash = new SHA256Managed())
    {
        return hash.ComputeHash(bytes);
    }
}

public static byte[] ByteConcat(byte[] left, byte[] right)
{
    if (null == left)
    {
        return right;
    }

    if (null == right)
    {
        return left;
    }

    byte[] newBytes = new byte[left.Length + right.Length];
    left.CopyTo(newBytes, 0);
    right.CopyTo(newBytes, left.Length);

    return newBytes;
}

【讨论】:

  • 我知道框架中可用的 HMACSHA256,但我想尝试我自己的,因为我有研究尝试对 KEY 进行一些更改并在我的结果和标准结果之间进行比较,所以我原则上,要确保我的代码在进行更改之前将结果作为标准返回
  • 您的代码结果与我的代码结果相同,但不符合标准 HMAC-SHA256 哈希作为本站HMAC Generator / Tester Tool
  • 我已经使用 .Net 框架版本进行了测试,两者返回相同。我不确定你指的是什么标准。我也对此进行了测试:freeformatter.com/hmac-generator.html,所有这些都完全匹配。
  • 谢谢@loopedcode,我错误地使用 32 作为 SHA256 块大小。非常感谢您的帮助
猜你喜欢
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-29
  • 2023-01-25
  • 2021-08-17
  • 2020-10-18
  • 2016-11-03
相关资源
最近更新 更多