检索哈希值后使用c#HashAlgorithm



我有一个哈希算法对象(在本例中为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库中的哈希实现(非常宽松的库,所以你可以从代码中获得状态)。

请注意,对哈希扩展的攻击是众所周知的,因此您可能需要重新查看您的协议。

如果你想使用标准算法实现,我建议你看看哈希树实现,这在文件共享协议中很常见。

最新更新