首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试使用C#.Net对HMAC-SHA256 256进行编码

尝试使用C#.Net对HMAC-SHA256 256进行编码
EN

Stack Overflow用户
提问于 2014-02-01 13:35:29
回答 1查看 5.3K关注 0票数 4

我尝试将HMAC-SHA256 256算法作为函数进行编码。

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

哪里

  • H是一个加密的散列函数,
  • K是一个向右填充的秘密键,在哈希函数的输入块大小上加上额外的零,如果它比该块大小长,则为原始键的散列。
  • M是要认证的消息,
  • ∥表示级联,
  • ⊕表示排他性或(异或),
  • opad是外垫(0x5c5c5c…)。5c5c,一个块长的十六进制常数),
  • ipad是内部填充物(0x363636…)3636,一个块长的十六进制常数)。

这是我的密码

代码语言:javascript
复制
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;
}

但是,当我尝试测试这段代码时,结果是Non-conforming到标准HMAC- the 256散列在标准internet网站上。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-01 14:00:49

以下是带有自定义HMAC生成的修改版本。主要要考虑的是,输入块大小在K中引用,是哈希算法块大小;没有返回散列字节长度。对于SHA256,块大小为64字节。我相信你用的是32字节的块大小。您可以在这里找到不同的块大小引用:Algorithm

代码语言:javascript
复制
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;
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21498696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档