対称暗号化( AesManagedRfc2898DeriveBytes
など)で使用するために、ユーザーが指定した文字列パスワードから暗号化キーと初期化ベクトルを安全に生成するために使用しています。
パスワードのSHA1ハッシュをsaltパラメーターとして使用していますRfc2898DeriveBytes
。それは大丈夫ですか?そうでない場合は、どこから塩を入手すればよいですか?復号化するときに同じソルトが必要になりますよね?したがって、暗号化されていない場所、つまりセキュリティで保護されていない場所に保存する必要があります。安全に保管しなければならない場合は、別の「パスワード」になりますね。
void SecureDeriveKeyAndIvFromPassword(string password, int iterations,
int keySize, int ivSize, out byte[] key, out byte[] iv)
{
// Generate the salt from password:
byte[] salt = (new SHA1Managed()).ComputeHash(Encoding.UTF8.GetBytes(password));
// Derive key and IV bytes from password:
Rfc2898DeriveBytes derivedBytes = new Rfc2898DeriveBytes(password, salt, iterations);
key = derivedBytes.GetBytes(keySize);
iv = derivedBytes.GetBytes(ivSize);
}
私は定数(ハードコードされた)ソルトを使用しているのを見てきました、そして人々がそれについて不平を言っているのを見ました。パスワードからソルトを導出する方が良いと思いましたが、これが最適なソリューションかどうかはわかりません。
間もなく、暗号化する必要のあるファイルと、ユーザーが入力したパスワード文字列があります。Rfc2898DeriveBytes
安全な暗号化キーとIVを導出するために適切に使用するにはどうすればよいですか?
ありがとう。
編集:
回答ありがとうございます。ソルトの主な(たぶん唯一の?)目的は、レインボーテーブルの生成を不可能にすることであることがわかりました。「P @ $$ w0rd」のハッシュは、可能なものごとに異なるハッシュを持つため、事前に生成することはできません。塩の値。私はこれを完全に理解していますが...これは本当に対称暗号化に関連していますか?ハッシュをどこにも保存していませんよね?したがって、攻撃者が考えられるすべてのパスワードの組み合わせに対応するレインボーテーブルを持っていたとしても、攻撃者は多くのことを実行できません。
したがって、私の質問は次のとおりです。対称暗号化アルゴリズム(.NETのAesManagedなど)で使用する場合、パスワードから派生した(またはハードコードされた)ソルトを使用する場合と比較して、各暗号化操作でランダムソルトを使用する利点はありますか?