2013-08-26 36 views
3

我有一個散列算法對象(在本例中爲SHA1),我用數據提供,以便在調用Result屬性後最終獲得散列結果。檢索散列值後使用c#HashAlgorithms

問題是,一旦調用了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

OT:你可能不應該使用SHA1加密任何東西...... –

+0

我對結果做RSA。但是這與問題無關 – galbarm

+0

這就是我說OT的原因。但是,斑點... –

回答

4

你需要調用HashFinal取得結果之前:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.hashalgorithm.hashfinal.aspx

基於途中散列算法作品(塊密碼),則不能獲得準確的中間結果因爲它不會正確計算中間數據塊。這是因爲它必須填充最後的數據塊以確保正確的值並保持密碼「強」。換句話說,由於數據塊依賴於先前的塊,因此您需要所有數據才能生成正確的結果。 .NET試圖通過在最終確定之前拒絕對密碼結果的訪問來幫助你。您提供散列所有數據,然後確定以獲得正確計算的結果。

我會向你提出這個問題:爲什麼你需要中間結果?是否有一個原因可以從另一個角度來解決或解決?告訴我們爲什麼,我們可以幫助替代品。

您還應該注意在使用後妥善關閉/處置您的流。

+0

謝謝,但它並沒有回答基於散列的工作方式的問題 – galbarm

+0

,因爲它不能正確計算塊密碼部分則無法獲得中間結果。你提供所有數據,然後最終確定正確的計算結果。爲什麼你需要中間結果? – Haney

+1

謝謝。首先,關於你的分組密碼是如何工作的解釋 - 它仍然有可能得到一個「中間」的結果,如果內部執行將進行最終的一步,但不知何故保存以前的狀態以供將來使用,並給予哈希後恢復結果。這是我所希望的解決方案。關於爲什麼我需要中間結果:請參閱下一個註釋 – galbarm

2

我想你不能這樣做使用HashAlgorithm。所以如果你想這樣做,你可能不得不依賴於你可以改變的哈希實現,比如Bouncy Castle庫中的哈希實現(非常寬鬆的庫,所以你可以從代碼中獲得狀態)。

被警告說哈希擴展的攻擊是衆所周知的,所以你可能想再看看你的協議。

如果你想使用標準算法的實現,我會建議你看看hash tree實現,這是其中的文件共享協議中都很常見。

+0

謝謝。使用外部庫不是我的選擇,但感謝你和DavidH的回答,我明白解決方案只能是改變設計本身,所以根本不需要中間設備。 – galbarm

+0

@galbarm這絕對是最好的選擇。如前所述,如果您查看其他協議,那麼哈希樹可能就是要走的路。中間狀態沒有在任何標準中定義,並且對於散列實現可能不同。 –