检索哈希值后使用c#HashAlgorithm
本文关键字:c#HashAlgorithm 哈希值 检索 | 更新日期: 2023-09-27 18:29:07
我有一个哈希算法对象(在本例中为SHA1),我向其提供数据,以便在调用result属性时最终获得哈希结果。
问题是,一旦调用了m_HashAlgorithm.Hash属性,该对象就不能再用于馈送。如果我试着喂它,我会得到:System.Security.Cryptographic.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;
}
}
在获得结果之前需要调用HashFinal
:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.hashalgorithm.hashfinal.aspx
根据哈希算法的工作方式(分组密码),您无法获得准确的中间结果,因为它无法在数据中间正确计算块。这是因为它必须填充最终的数据块,以确保正确的值,并保持加密"强大"。换句话说,由于数据块依赖于先前的块,因此需要所有数据才能生成正确的结果。NET试图通过在最终确定之前拒绝访问密码结果来帮助您解决这一问题。您向散列提供所有数据,然后最后确定以获得正确计算的结果。
我想问你一个问题:为什么你需要中间结果?有什么原因可以从不同的角度来处理或解决吗?告诉我们为什么,我们也许可以帮助我们找到替代方案。
您还应注意在使用后正确关闭/处理您的流。
我想您不能使用HashAlgorithm
来完成此操作。因此,如果你想做到这一点,你可能必须依赖一个可以更改的哈希实现,比如Bouncy Castle库中的哈希实现(非常宽松的库,所以你可以从代码中获得状态)。
请注意,对哈希扩展的攻击是众所周知的,因此您可能需要重新查看您的协议。
如果你想使用标准算法实现,我建议你看看哈希树实现,这在文件共享协议中很常见。