暗号化に挑戦

ではRfc2898DeriveBytesクラスを利用してSaltと暗号鍵を生成しています。

Rfc2898DeriveBytes (string password, byte[] salt);

saltを指定すると同じ暗号鍵をつくります。また

Rfc2898DeriveBytes (string password, int saltSize);
// saltSizeは8以上を指定すること

このようにサイズを指定するとランダムsaltを生成します。

さて、本当にランダムなのでしょうか? 何回も同じことをくり替えていると同じsaltが生成されるということはないのでしょうか?

このようにすると生成されたソルトを集めて重複している数を知ることができます。

lenの値を大きくしても重複することはないようです。

それもそのはずsaltSize=8を指定しても生成されるsaltは256の8乗あります。256の8乗を計算すると18,446,744,073,709,551,616。約1844京もある巨大な数です。1000万回や1億回繰り返したところでダブることはまずありません。

また生成される暗号鍵は256bitの場合、2の256乗であり、約1.15×10の77乗です。異なるsaltやパスワードから同じ暗号鍵が生成される可能性もほとんどありません。

RandomクラスのNextBytesメソッドを使えば同じようなことができますが、暗号強度が高いランダムな数値を生成するのには適してしません。ためしに以下のような処理をさせてみました。

sizeに8以上の値を設定したときは基本的に重複はしません。しかし小さな値を設定すると重複しやすくなります。

ループ10万回

4バイト以上 重複 0
3バイト 重複 約300

ループ100万回

5バイト以上 重複 0
4バイト 重複 約100

ループ300万回

6バイト以上 重複 0
5バイト 重複 約10

このような結果になりました。変なことはしないでRfc2898DeriveBytes クラスのようなものを使ったほうが無難です。