检索哈希值后使用c#hash算法

检索哈希值后使用c#hash算法,c#,hash,cryptography,sha1,sha,C#,Hash,Cryptography,Sha1,Sha,我有一个hash算法对象(本例中为SHA1),我向其提供数据,以便在调用result属性时最终获得哈希结果 问题是一旦调用了m_HashAlgorithm.Hash属性,对象就不能再用于馈送。 如果我尝试喂它,我会得到: System.Security.Cryptography.Cryptography意外操作异常:在检索哈希值之前,必须完成哈希 我需要能够得到一个中间的散列结果,但继续馈送,然后再得到另一个结果。 有没有办法做到这一点 private readonly HashAlgorith

我有一个hash算法对象(本例中为SHA1),我向其提供数据,以便在调用result属性时最终获得哈希结果

问题是一旦调用了m_HashAlgorithm.Hash属性,对象就不能再用于馈送。 如果我尝试喂它,我会得到: System.Security.Cryptography.Cryptography意外操作异常:在检索哈希值之前,必须完成哈希

我需要能够得到一个中间的散列结果,但继续馈送,然后再得到另一个结果。 有没有办法做到这一点

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

根据哈希算法(分组密码)的工作方式,您无法获得准确的中间结果,因为它无法在数据中间正确计算块。这是因为它必须填充最后的数据块,以确保正确的值并保持加密“强”。换句话说,由于数据块依赖于先前的块,因此需要所有数据来生成正确的结果。NET试图通过在最终确定之前拒绝访问密码结果来帮助您解决这一问题。您向散列输入所有数据,然后完成以获得正确计算的结果

我要向你们提出这个问题:为什么你们需要中间结果?有什么原因可以从不同的角度来探讨或解决吗?告诉我们原因,也许我们可以帮助我们找到替代方案


您还应注意在使用后正确关闭/处置您的流。

我想您不能使用。因此,如果您想这样做,您可能必须依赖可以更改的哈希实现,例如Bouncy Castle库中的哈希实现(非常允许的库,因此您可以从代码中获取状态)

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


如果您想使用标准算法实现,我建议您查看文件共享协议中常见的实现。

OT:您可能不应该将SHA1用于任何加密…我对结果使用RSA。但这与问题无关这就是我说OT的原因。但是好的发现…@MitchWheat取决于它的使用方式,但是对于数字签名来说,它不是最好的。但是,当SHA-1最终被破解时,您仍然需要私钥来控制签名函数,以便执行任何有用的操作。当然,对于新协议,请使用SHA-256或SHA-512的形式。谢谢,但它不会根据哈希的工作方式回答问题,您无法获得中间结果,因为它无法正确计算分组密码部分。您向它提供所有数据,然后最终确定以获得正确计算的结果。为什么需要中间结果?谢谢。首先,关于您对分组密码工作原理的解释,如果内部实现将执行finalize步骤,但以某种方式保存以前的状态以供将来使用,并在给出散列结果后将其还原,则仍然可以获得“中间”结果。这就是我所希望的解决方案。关于为什么需要中间结果:请参阅下一篇评论。该程序计算从外部位置实时到达的流(即不是文件)的哈希值。程序中的配置更改可以表示流在未知的持续时间(即中间点)内不再到达,但此配置可以再次更改以表示相同的流再次到达。在这一点上,我必须继续我刚才停下来的地方。关于第一个问题-是的,您肯定可以保留发送进来的数据的字节流或数组,并在内部计算当前进度的最终结果。关于第二点,我不确定散列如何帮助你,但很明显,这对于这个问题来说太深入了。。。我会在内部进行中间步骤的最后一步。应该很好,谢谢。使用外部库不是我的选择,但由于您和DavidH的回答,我知道解决方案只能是更改设计本身,这样就根本不需要中间库。@galbarm这绝对是最好的选择。如前所述,如果您查看其他协议,则哈希树可能是一种方法。任何标准中都没有定义中间状态,对于哈希实现,中间状态可能不同。