哈希代码与HMAC-SHA1中的TransformBlock和ComputeHash方法不同

时间:2017-06-19 04:06:45

标签: .net encryption hmacsha1

当我使用TransformBlock和TransformFinalBlock作为缓冲区时,哈希码与使用HMAC-SHA1中的ComputeHash()方法计算哈希码不同。为什么?以及如何解决这个问题。

2 个答案:

答案 0 :(得分:3)

由于您没有提供任何代码,因此无法确定,但是通灵调试表明您假设TransformFinalBlock返回了HMAC,它只是计算了{{ {1}}属性。

Hash

输出

byte[] data = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 };
HMACSHA1 hmac = new HMACSHA1(new byte[] { 1, 2, 3, 4, 5 });
Console.WriteLine($"ComputeHash: {Convert.ToBase64String(hmac.ComputeHash(data))}");
Console.WriteLine($"TransformFinalBlock: {Convert.ToBase64String(hmac.TransformFinalBlock(data, 0, data.Length))}");
Console.WriteLine($"get_Hash: {Convert.ToBase64String(hmac.Hash)}");

所以,答案是忽略TransformFinalBlock(它回显输入)的结果,然后调用get_Hash。

答案 1 :(得分:1)

根据documentation HMACSHA1 将密钥与输入消息混合以生成最终哈希值,然后再混合并进行哈希处理......

如果您未能提供密钥,则会随机生成该密钥,从而导致不同哈希。

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Security.Cryptography;
using System.Text;

[TestClass]
public class HashTests
{
    [TestMethod]
    public void HashTest()
    {
        var keyBytes = Encoding.UTF32.GetBytes("my secret key");
        var textBytes = Encoding.UTF32.GetBytes("my tiny little text");

        var hash1 = GetHash1(textBytes, keyBytes);
        var hash2 = GetHash2(textBytes, keyBytes);

        Assert.AreEqual(hash1.Length, hash2.Length);

        for (int i = 0; i < hash1.Length; i++)
            Assert.AreEqual(hash1[i], hash2[i]);
    }

    private byte[] GetHash2(byte[] textBytes, byte[] key)
    {
        using (var alg = new HMACSHA1(key))
            return alg.ComputeHash(textBytes);
    }

    private byte[] GetHash1(byte[] input, byte[] key)
    {
        var size = input.Length;
        using (var alg = new HMACSHA1(key))
        {
            int offset = 0;

            while (input.Length - offset >= size)
                offset += alg.TransformBlock(input, offset, size, input, offset);

            alg.TransformFinalBlock(input, offset, size - offset);
            return alg.Hash;
        }
    }
}