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