2013-08-05 84 views
2

我的印象是,基於密碼的密鑰派生函數的要點是每次都以相同的方式從密碼生成密碼安全的密鑰流,因此可以依靠密碼來生成密碼中的加密密鑰。帶有Rfc2898DeriveBytes的PBKDF2爲相同的輸入產生不同的輸出?

從我在線閱讀的內容,包括stack overflow,這似乎是預期的用途。

所以當我產生不同的輸出爲我認爲是相同的輸入我假設我使用它錯了。爲了測試這個,我寫了一個Rfc2898DeriveBytes的測試用例,按照文檔中的建議使用它。

[TestMethod] 
public void PBKDF2_Works() { 
    var salt = new byte[] { 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0D, 0x15 }; 
    var password = "password"; 
    var iterations = 1000; 
    var len = 48; 

    var gen1 = new Rfc2898DeriveBytes(password, salt, iterations); 
    var gen2 = new Rfc2898DeriveBytes(password, salt, iterations); 

    var bytes1 = gen1.GetBytes(len); 
    var bytes2 = gen2.GetBytes(len); 
    Assert.AreEqual(bytes1, bytes2); 
} 

這個測試用例失敗了,我找不到原因。我是否錯誤地使用了函數,或者我誤解了它應該用於什麼?

編輯:好了,測試方法是以上一個有缺陷的測試,因爲我沒有使用斷言的集合形式。我認爲AreEqual會在參數上調用.Equals,以及爲了比較內容而實現的集合。

我有是,我認爲同樣的參數Rfc2898DeriveBytes正在產生對於相同的輸入不同的輸出,但輸入是微妙的不同的問題:

我生成的16字節的鹽,並存儲在數據庫中,但由於字段長度的原因,當鹽被解密時,前16個字節是相同的(所以我認爲它使用的是相同的信息),但是後面跟着另外48個字節的0,因此輸入是不同。

+0

啊,是的,正確的填充是問題。常見的錯誤,儘管在加密中,左填充是一個問題更常見;將整數編碼爲八位字符串(又名字節數組)通常會導致類似的問題。如果它讓你感覺更快樂,我就會在常用的加密庫,測試框架等中看到這種情況。 –

回答

3

MSTest的Assert.AreEqual通常會對集合進行引用相等比較(除非它是覆蓋Equals的自定義集合),這通常不是您想要的。嘗試使用CollectionAssert.AreEqual

+0

好的,那是一個愚蠢的錯誤,我將編輯這個問題以更真實地反映真實的代碼,後面有問題。謝謝。 – danpalmer

+0

將此標記爲答案,因爲它回答了所提問題的當前問題,並且對一般情況有用。閱讀編輯以瞭解問題的完整說明。 – danpalmer

相關問題