我有一个用例,我想创建第二个HMAC,其中第一个HMAC和一些数据被合并。
我想了解为什么测试用例3正在创建错误的 hmac,这令人困惑,因为1和2正在创建相同的哈希值。
代码:
void Main()
{
{ // 0. Create a HMAC
byte[] keyHmac = new byte[] { 255 };
var hmac = new HMACSHA512(keyHmac); // 1st HMACSHA512 ctor
var result = hmac.ComputeHash(new byte[] { 1, 2, 3 });
Console.Out.WriteLine($"0. - {Convert.ToBase64String(result)}");
}
Console.Out.WriteLine("\r\nThe following MACs should be all equal!\r\n");
{ // 1. Create a HMAC than add a byte to the result and create a second HMAC
byte[] keyHmac = new byte[] { 255 };
var hmac = new HMACSHA512(keyHmac); // 1st HMACSHA512 ctor
var result = hmac.ComputeHash(new byte[] { 1, 2, 3 });
result = hmac.ComputeHash(result.Concat(new byte[] { 7 }).ToArray());
Console.Out.WriteLine($"1. - {Convert.ToBase64String(result)}");
}
{ // 2. Create a HMAC than add a byte to the result and create a second HMAC with a new instance
byte[] keyHmac = new byte[] { 255 };
var hmac = new HMACSHA512(keyHmac); // 1st HMACSHA512 ctor
var result = hmac.ComputeHash(new byte[] { 1, 2, 3 });
hmac = new HMACSHA512(keyHmac); // 2nd HMACSHA512 ctor
result = hmac.ComputeHash(result.Concat(new byte[] { 7 }).ToArray());
Console.Out.WriteLine($"2. - {Convert.ToBase64String(result)}");
}
{ // 3. Create a HMAC from a stream than add a byte to the result and create a second HMAC
byte[] keyHmac = new byte[] { 255 };
var hmac = new HMACSHA512(keyHmac);
using (var resultStream = new MemoryStream())
{
using (var hmacStream = new CryptoStream(resultStream, hmac, CryptoStreamMode.Write))
{
new MemoryStream(new byte[] { 1, 2, 3 }).CopyTo(hmacStream);
}
}
var result = hmac.Hash;
result = hmac.ComputeHash(result.Concat(new byte[] { 7 }).ToArray());
Console.Out.WriteLine($"3. - {Convert.ToBase64String(result)}");
}
{ // 4. Create a HMAC from a stream than add a byte to the result and create a second HMAC with a new instance
byte[] keyHmac = new byte[] { 255 };
var hmac = new HMACSHA512(keyHmac);
using (var resultStream = new MemoryStream())
{
using (var hmacStream = new CryptoStream(resultStream, hmac, CryptoStreamMode.Write))
{
new MemoryStream(new byte[] { 1, 2, 3 }).CopyTo(hmacStream);
}
}
var result = hmac.Hash;
hmac = new HMACSHA512(keyHmac);
result = hmac.ComputeHash(result.Concat(new byte[] { 7 }).ToArray());
Console.Out.WriteLine($"4. - {Convert.ToBase64String(result)}");
}
}
输出:
0. - J0x6KRHzGh1nTLL+a+pL8H9PJyl1b9/rL7D0j3S1DBpMduct37uMi0mBFEOdkfrLs2Ipn39yoV6GaRoEK+hU7A==
The following MACs should be all equal!
1. - mVd7YQ7AbmRfH57AprAuU1vlSuOucvg+NbUFl7eNurPuvGS/Xrko2Kz3d9vUGXr0P287dOgEKQJDNfMkN2xi5Q==
2. - mVd7YQ7AbmRfH57AprAuU1vlSuOucvg+NbUFl7eNurPuvGS/Xrko2Kz3d9vUGXr0P287dOgEKQJDNfMkN2xi5Q==
3. - DVncxk/dEYhmmpK5qEnVg0Pc0/MUe8APbAiyZrh+ba35oGv2TGCkFco3gFVZ2gl+h3DpcqP7VbmuthBmCvSKlg==
4. - mVd7YQ7AbmRfH57AprAuU1vlSuOucvg+NbUFl7eNurPuvGS/Xrko2Kz3d9vUGXr0P287dOgEKQJDNfMkN2xi5Q==
答案 0 :(得分:1)
那是因为在除了3之外的所有方法中,你在第一个哈希计算和第二个哈希计算之间重新初始化你的hmac。要在3中执行相同的操作,请尝试以下操作:
{
// 3. Create a HMAC from a stream than add a byte to the result and create a second HMAC
byte[] keyHmac = new byte[] {255};
var hmac = new HMACSHA512(keyHmac);
using (var resultStream = new MemoryStream()) {
using (var hmacStream = new CryptoStream(resultStream, hmac, CryptoStreamMode.Write)) {
new MemoryStream(new byte[] {1, 2, 3}).CopyTo(hmacStream);
}
}
var result = hmac.Hash;
hmac = new HMACSHA512(keyHmac);
result = hmac.ComputeHash(result.Concat(new byte[] {7}).ToArray());
Console.Out.WriteLine($"{Convert.ToBase64String(result)}");
}
答案 1 :(得分:1)
在第3种情况下,您通过拨打TransformBlock
来混淆TransformFinalBlock
/ CryptoStream
(由ComputeHash
使用)的来电。这两种方法似乎都干扰了另一种方法对状态机的假设。
使用一种方法或另一种方法很好,但混合它们并不会那么热。
如果不是使用CryptoStream而是使用HashAlgorithm.ComputeHash(Stream)
,那么第三种情况应该有效。