パスワードベースのキー派生関数のポイントは、毎回同じ方法でパスワードから暗号的に安全なキーストリームを生成することであり、パスワードから暗号化キーを生成するために信頼できるという印象を受けました。
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 によって、入力が異なっていました。