我有一个哈希算法对象(在本例中为SHA1),我提供数据以便在调用Result属性时最终得到散列结果。
问题是,一旦调用了m_HashAlgorithm.Hash属性,该对象就不能再用于提供。 如果我尝试喂它,我得到: System.Security.Cryptography.CryptographicUnexpectedOperationException:必须在检索哈希值之前完成哈希。
我需要能够得到一个中间哈希结果,但是继续喂食并在以后获得另一个结果。 有没有办法实现它?
private readonly HashAlgorithm m_HashAlgorithm;
public DigitalSignatureCreator(HashAlgorithm hashAlgorithm)
{
m_HashAlgorithm = hashAlgorithm;
m_MemoryStreamEncrypt = new MemoryStream();
m_CryptoStreamEncrypt = new CryptoStream(m_MemoryStreamEncrypt, m_HashAlgorithm, CryptoStreamMode.Write);
}
public void Feed(byte[] data, int offset, int count)
{
m_CryptoStreamEncrypt.Write(data, offset, count);
}
public byte[] Result
{
get
{
return m_HashAlgorithm.Hash;
}
}
答案 0 :(得分:4)
您需要在获得结果之前致电HashFinal
:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.hashalgorithm.hashfinal.aspx
基于哈希算法的工作方式(块密码),您无法获得ACCURATE中间结果,因为它不会在数据中正确计算块。这是因为它必须填充最终数据块以确保正确的值并保持加密“强”。换句话说,由于数据块依赖于先前的块,因此您需要所有数据来生成正确的结果。 .NET试图通过拒绝访问密码结果来帮助您解决这个问题,直到最终确定。您将散列所有数据,然后最终确定以获得正确计算的结果。
我向你提出这个问题:为什么你需要中间结果?您是否有理由从不同的角度接近或解决?告诉我们原因,我们也许可以为替代方案提供帮助。
使用后,您还应注意妥善关闭/处理您的溪流。
答案 1 :(得分:2)
我猜你不能使用HashAlgorithm
来做到这一点。因此,如果你想这样做,你可能不得不依赖于你可以改变的哈希实现,例如Bouncy Castle库中的哈希实现(非常宽松的库,所以你可以从代码中获取状态)。
请注意,对哈希扩展的攻击是众所周知的,因此您可能需要再次查看协议。
如果您想使用标准算法实现,我建议您查看文件共享协议中常见的hash tree实现。