web-dev-qa-db-ja.com

パスワードハッシュ用のPBKDF2のパラメーター

パスワードのハッシュを保存するためにSHA-256でPBKDF2を使用しています。次のパラメーターを使用します。

number of iterations desired        = 1024
length of the salt in bytes         = 16
length of the derived key in bytes  = 4096 

しかし、最近、おそらくパラメータが正しく選択されていないことがわかりました。

たとえば wiki page はこう言います:

標準は2000年に作成され、推奨される最小反復回数は1000回でした。2005年の時点で、Kerberos標準は4096回の反復を推奨しています

つまり、おそらく私はこの数を増やす必要があります

そして

標準では、少なくとも64ビットのソルト長を推奨しています

つまり、私の塩分の長さは大丈夫です 低すぎる (Neil Smithlineに感謝)。しかし 標準の検索 の場合、推奨されるソルトの長さについての言及を見つけることができませんでした。

派生キーの長さを探して、これを見つけたとき 良い答え

パスワードハッシュにPBKDF2を使用する場合、無視できないセキュリティマージンで12バイトの出力で問題ないはずです。

多すぎる数をとったので、おそらく意味がありません。


したがって、私の質問はです:このパスワードハッシュのシナリオ(2016年の時点)について、誰でも適切なパラメータ(正当化/リンクがある場合があります)を表示できますか?また、派生したキーの長さが常に私と同じ長さになることを保証できますか?

12
Salvador Dali

あなたの出発点

PBKDF2-HMAC-SHA-256

必要な反復回数= 1024

バイト単位のソルトの長さ= 16

派生キーの長さ(バイト)= 4096


アルゴリズム

OK-PBKDF2-HMAC-SHA-256は確かな選択ですが、最新の64ビットCPUで実行している場合は、代わりにPBKDF2-HMAC-SHA-512を強くお勧めします。SHA-512には64ビット操作が必要なためです。最新のGPUは64ビットも実行しないため、GPUベースの攻撃者の利点のマージンが減少します。


16バイトのソルトは、暗号的にランダムで、パスワードごとに一意である限り、問題ありません。通常の推奨は12〜24バイトの範囲であり、16は非常に堅固であると見なされています。


出力と反復

4096バイトの出力はACTIVELY BAD!SHA-256のネイティブ出力サイズは32バイトです。 PBKDF2/RFC2898 は、この場合、最初に(左端の)32バイトを取得するために最初に1024回の反復を実行し、次に次の32バイトに対してさらに1024回の反復を実行することを示しています。合計で、要求した出力の完全な4096バイトを取得します。

したがって、合計131072回の反復を実行し、4096バイトの出力を得ました。攻撃者は合計1024回の反復を行い、32バイトの出力を最初の(左端の)32バイトの出力と比較します-それらが同じである場合、正しく推測されます! すべての攻撃者に128:1のアドバンテージを与えました!

代わりに、速度に満足している場合は、32バイトの出力で131072回の反復を実行する必要があります。現在の時間と同じ時間(つまり、無料です)を費やし、攻撃者はさらに128倍の時間を費やす必要があります。彼らは今よりも時間!

  • 注:PBKDF2-HMAC-SHA-512に移動する場合、最大64バイトの出力を使用でき、各反復にわずかに時間がかかります。

ハッシュ関数のネイティブ出力よりも多くのパスワードハッシュの出力を取得しないでください。つまり、SHA-1の場合は20バイト、SHA-256の場合は32バイト、SHA-512の場合は64バイトです。必要に応じて保存する容量を減らすこともできますが、計算量を節約することはできません。少なくとも28バイトの出力(224ビット、112ビットの2倍、3DESの公称セキュリティ)を保存することをお勧めします。

出力長の値は純粋なバイナリ出力であることに注意してください-BASE64またはhexifyする前に、そうする場合(個人的には、生のバイナリを保存します-使用するスペースが少なく、変換が1つ少なくなります)。

23
  1. 8バイトsaltは問題ありません。ランダムに生成されたときにグローバルに一意であり、それがsaltの目的です。一意性です。大きすぎることは問題ではないので、少しのストレージを無駄にすることを除いて、ハイサイドでの見積もりは問題ありません。

  2. 2バイト派生キーの長さに適しています(ほとんどのハッシュアルゴリズムは、16から64バイトの間で出力されます。ここで、64は過剰です)。 4096という値は間違いなく過剰です。実際には、バイトとビットを間違えているといいのですが。

  3. 反復は非常に簡単です。ハードウェアで可能な限り多くの回数を繰り返します。ログインに0.5秒かかる場合は、0.5秒を経過する前に実行できる反復の数をベンチマークします。 2020年、400 000はローエンドサーバーに適した値です(平均的なサーバーCPUはより多くの反復を処理できます)。

  4. SHA-256は、選択する必要がある場合に適したアルゴリズムです。 MD5、SHA-1、および既知の攻撃を持つその他のものは避けてください。それらはこの目的(MD5を含む)に対しても安全である可能性がありますが、攻撃はさらに良くなるだけであり、すでに部分的に壊れているものを使用しないこともできます。

パワー不足のシステム(Raspberry Piなど)で実行している場合は、安全性に応じて異なるハードウェアを検討するか、ログインに時間がかかるようにする必要があります。通常、ログインは1日に1回程度しか行われないため、アプリケーションによっては10秒待つのが妥当な場合があります。

7
Luc

私の最初の提案は、プラットフォームのデフォルトのパスワード保存メカニズムを使用することです。 PHPのような関数 password_hash は、パスワードの記憶からすべての心配と大騒ぎを取り除きます。

あなたがそれを行うことができないと仮定して、私はbcryptを使用することをお勧めします。 GPUで並列演算を使用する場合、bcryptを解読するのはより困難です。 scryptはメモリとCPUに負荷をかけます。 この答え は、これがすべて非常に詳細であることを説明しています。

何らかの理由でpbkdf2で立ち往生していると仮定します...

ソルト:この2013年の回答 によると、Thomas Porninによると、128ビットまたは16バイトで十分です。 Crackstationの推奨事項 は192ビットまたは24バイトです。その範囲のどこでも安全だと思います。個人的には、ソルトの長さ(ランダムデータの生成でハングしないと仮定)がハッシュパフォーマンスに実際に寄与しないため、24バイトを使用します。ソルトの生成には、必ず [〜#〜] csprng [〜#〜] を使用してください。

パスワードの長さ:Thomas Porninの回答では、12バイト、Crackstation 24が推奨されています。ここでも、私はより大きなサイズを使用する傾向がありますが、その範囲内のものは安全だと思います。

反復:反復の数は、許容できる限り多くする必要があります。だから、ハッシュのパフォーマンスのテストを開始します。私は0.05-0.10秒の推奨を見てきましたが、これらは単なる推定値だと思います。計算リソースに余裕がある場合は、おそらく少し高くすることができます(多すぎると認証が遅くなりすぎます)。計算リソースが不足している場合は、小さくしてください。

概要:

number of iterations desired        = max you can tolerate
length of the salt in bytes         = 16-24
length of the derived key in bytes  = 12-24
6
Neil Smithline