多くの場合、ハッシュ関数を直接使用するよりもPBKDF2をお勧めしますが、通常、PBKDF2を単一の無塩ハッシュと比較します。暗号化関数の複数の反復でPBKDF2を使用する場合、各反復で前のハッシュにパスワードとソルトを追加するとどのような利点がありますか?
疑似コード:
password="mypass0rd";
salt=random();
hash = password;
for (int i=0;i<1000;i++){
hash = sha512(hash+password+salt);
}
random()
を呼び出しますが、ほとんどの言語の組み込みPRNGは暗号セーフではありません。塩を生成するライブラリを入手すれば、余分な手間やバグの可能性を回避できます。sha512
の出力は生バイトですか、それとも16進数ですか?salt
は文字列または数値であり、sha512
への入力用にバイトに変換する方法を教えてください。構成とPBKDF2の重要な違いの1つは、PBKDF2がハッシュを直接ではなく、疑似ランダム関数(prf)(通常はHMAC)を使用することです。 SHA1とSHA2はprfsではないので、特定のセキュリティ証明はそれらに適用されません。
構造に関する理論的な問題の1つは、内部衝突や短いチェーンにぶつかる可能性があることです。ソルトとパスワードは各反復で保持されるため、実行中に同じハッシュを2回生成すると、ハッシュのサイクルが発生します。 (PBKDF2もこれの変種に悩まされていますが、注意が必要なことを示しています。)
だからあなたはあなたのループが次のように見える方が良いでしょう
hash = hmac-sha512(i + salt + password, hash)
しかし、他の人が指摘したすべての理由から、自分でロールするのではなく、PBKDF2、いぼなどを使用したほうがよいでしょう。
scryp tは、ほとんどすべての状況でPBKDF2より優れています。しかし、正しく使用することを学ぶのは難しいです。 PBKDF2はbcryptより優れています。
また、PBKDF2はパスワードハッシュ用ではなく、鍵の導出用に設計されていることにも注意してください。したがって、実際には必要としない機能や特性がいくつかあります。 (そして、それはそのコンポーネントにバグがあり、それはキーの派生にとってのみ重要であり、非常に珍しい状況です)。
私はPBKDF2を批判しているのと同じくらい、自分自身をロールするよりも、それを使用するほうが良いと思います。それに関する特定の問題は、パスワードハッシュで遭遇するものではありません。
Password Hashing Competition の展開をフォローすることをお勧めします。これは、パスワードハッシュ用のPBKDF2、scrypt、bcryptの後継を見つけるための試みです。ただし、当面は、利用可能な場合はscryptを使用するか、PBKDF2を使用してください。