Try To Code HMAC-SHA256 using C#.Net

拜拜、爱过 提交于 2019-12-14 00:32:11

问题


i try to coding HMAC-SHA256 Algorithm as Function

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

where

  • H is a cryptographic hash function,
  • K is a secret key padded to the right with extra zeros to the input block size of the hash function, or the hash of the original key if it's longer than that block size,
  • m is the message to be authenticated,
  • ∥ denotes concatenation,
  • ⊕ denotes exclusive or (XOR),
  • opad is the outer padding (0x5c5c5c…5c5c, one-block-long hexadecimal constant),
  • ipad is the inner padding(0x363636…3636, one-block-long hexadecimal constant).

and this my code

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;
}

but when i try to test this code the result Non-conforming to standard HMAC-SHA256 hashing on the standard internet web sites


回答1:


Here is the modified version with custom HMAC generation. Main thing to consider is that Input Block Size referred in the K, is the hash algorithm block size; not returned hashed byte length. For SHA256, block size is 64 bytes. I believe you were using 32byte block size. You can find different block size references here: 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;
}


来源:https://stackoverflow.com/questions/21498696/try-to-code-hmac-sha256-using-c-net

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!