web-dev-qa-db-ja.com

なぜ別の暗号化ハッシュ関数の複数の反復でPBKDF2を使用するのですか?

多くの場合、ハッシュ関数を直接使用するよりもPBKDF2をお勧めしますが、通常、PBKDF2を単一の無塩ハッシュと比較します。暗号化関数の複数の反復でPBKDF2を使用する場合、各反復で前のハッシュにパスワードとソルトを追加するとどのような利点がありますか?

疑似コード:

password="mypass0rd";
salt=random();
hash = password;
for (int i=0;i<1000;i++){
    hash = sha512(hash+password+salt);
}
3
gluefan
  1. 自分の暗号をロールバックしないでください。一般に、(名前を指定するのではなく)何らかの暗号プリミティブ(SHA-512、AESなど)を直接呼び出す場合は、このルールに違反しています。クリプト実装のバグを回避するのは難しくないと思うなら、 マタサノのクリプトチャレンジ を試すことをお勧めします。
  2. yourコードの少ない行。これは、あなたが何かを台無しにする可能性が少ないことを意味します。また、よりクリーンでメンテナンスしやすいコードを意味します。
  3. 構成可能な反復カウント。確かに、コード内の反復変数を変更できますが、すでに横になっているすべてのハッシュについてはどうでしょうか。 PBKDF2を実装するライブラリには、各ハッシュの反復回数を格納および取得する組み込みの方法があります。
  4. RNGバグを回避します。コードはrandom()を呼び出しますが、ほとんどの言語の組み込みPRNGは暗号セーフではありません。塩を生成するライブラリを入手すれば、余分な手間やバグの可能性を回避できます。
  5. 移植性。バックエンドをアップグレードまたは変更する必要がありますか?おそらく、ユーザーのレコードと古いハッシュを新しいフレームワークにコピー(データベースのエクスポート/インポート)するだけです。そうでない場合は、新しいフレームワーク用のカスタムハッシュアルゴリズムを書き換えて、実装の違いにぶつかる必要があります。
    • sha512の出力は生バイトですか、それとも16進数ですか?
    • パスワードにはどの文字エンコーディングを使用しましたか?
    • saltは文字列または数値であり、sha512への入力用にバイトに変換する方法を教えてください。
5
bonsaiviking

構成とPBKDF2の重要な違いの1つは、PBKDF2がハッシュを直接ではなく、疑似ランダム関数(prf)(通常はHMAC)を使用することです。 SHA1とSHA2はprfsではないので、特定のセキュリティ証明はそれらに適用されません。

構造に関する理論的な問題の1つは、内部衝突や短いチェーンにぶつかる可能性があることです。ソルトとパスワードは各反復で保持されるため、実行中に同じハッシュを2回生成すると、ハッシュのサイクルが発生します。 (PBKDF2もこれの変種に悩まされていますが、注意が必要なことを示しています。)

だからあなたはあなたのループが次のように見える方が良いでしょう

hash = hmac-sha512(i + salt + password, hash)

しかし、他の人が指摘したすべての理由から、自分でロールするのではなく、PBKDF2、いぼなどを使用したほうがよいでしょう。

PBKDF2の代替

scryp tは、ほとんどすべての状況でPBKDF2より優れています。しかし、正しく使用することを学ぶのは難しいです。 PBKDF2はbcryptより優れています。

また、PBKDF2はパスワードハッシュ用ではなく、鍵の導出用に設計されていることにも注意してください。したがって、実際には必要としない機能や特性がいくつかあります。 (そして、それはそのコンポーネントにバグがあり、それはキーの派生にとってのみ重要であり、非常に珍しい状況です)。

私はPBKDF2を批判しているのと同じくらい、自分自身をロールするよりも、それを使用するほうが良いと思います。それに関する特定の問題は、パスワードハッシュで遭遇するものではありません。

PBKDF2/scrypt/bcryptの後継

Password Hashing Competition の展開をフォローすることをお勧めします。これは、パスワードハッシュ用のPBKDF2、scrypt、bcryptの後継を見つけるための試みです。ただし、当面は、利用可能な場合はscryptを使用するか、PBKDF2を使用してください。

1