检索哈希值后使用c#HashAlgorithm

时间:2013-08-26 15:40:30

标签: c# hash cryptography sha1 sha

我有一个哈希算法对象(在本例中为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;
    }
}

2 个答案:

答案 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实现。