web-dev-qa-db-ja.com

パスワードハッシュ証明SHA-3

私はパスワードハッシュを強化する必要があるが、追加の依存関係を持ち込むことが許可されていない状況にあるので、私は誰もが反対していると思われる1つのこと、つまり独自の実装を展開することを余儀なくされています。

SHAファミリーは高速ハッシュと見なされているため、パスワードハッシュには適していないようです。また、繰り返しハッシュハッシュによってエントロピーが失われるリスクもあります。

「低速ハッシュ」の背後にある意図は、CPU時間とメモリ要件の増加にあると思われるため、次の戦略を考案しました。

  • パスワードはSHA-3 512を介してハッシュされます
  • ハッシュ値はシードシーケンスを通じてmt19937 PRNGに送られます。
  • 長いランダムシーケンスが再ハッシュされるように生成されます
  • 同じ回数をn回繰り返します
  • 最終的なハッシュ値は、すべてのシーケンスを裏返しにハッシュすることから得られます

これにより、公平に構成可能な追加の作業量とメモリ要件が導入されるようです。

ですから、私の質問は、これが妥当な戦略であるかどうか、そしてもしそうなら、どのようなシーケンスの長さと再帰の深さで十分かということです。

更新:

クランプを使用して、ダイジェストサイズが224、256、384、512のSHA2、RealSHA3、Keccakの合計12のプロセスの各ステップのハッシュアルゴリズムも組み込んで、実装を少し拡張しました。セレクターとしても使用できます。

全体として、単一の単純なSHA3ハッシュと比較すると、この実装は約100k倍遅く、かなり深く、任意に分岐する再帰を介して追加の〜20 MB RAMのコストが発生し、最終的なハッシュが生成されます。最小限のターゲットプラットフォームの仕様を考慮して、妥当な制限内にとどまりながら、余裕があります。しかし、おそらく同じくらい重要なことですが、これは、単純な「n回リハッシュ」アプローチと比較して、計算の多様性をさらにもたらし、複数のハッシュアルゴリズムを使用します。PRN生成はかなり大きな内部状態であり、std::seed_seqには常に完全なハッシュが供給されます出力し、値の追加の「条件付け」を実行します。最後に、いくつかの倍精度浮動小数点演算を追加してすべてを結合し、手順全体のGPU/ASICを非友好的にします。

4 Ghz i7 CPUでは、ハッシュに5000ナノ秒から500ミリ秒かかるようになりました。パスワードで許可されている合計95の記号を考慮し、8スレッドまでの完全なスケーリングを想定すると、このPCで6文字のパスワードのすべての可能な組み合わせを試すには最大1450年、8文字のパスワードでは100kを使用して最大130年かかります。このようなCPUは、かなり厳しいようです。

これは十分に「強化された」と考えられていますか?そうでない場合、どうすれば改善できますか?

2
dtech

Argon2のような他の依存関係を含める必要がない、これに対する1つの解決策があります。 OpenPGPで使用される String-to-Key またはS2Kと呼ばれるアルゴリズムを実装できます。このアルゴリズムは、繰り返しパスワードとソルトをハッシュ関数に渡すことで機能します。パスワードとソルトは、ハッシュ関数がそれを処理するために無視できない時間を要するように十分に繰り返されます。これは非常にシンプルで遅いKDFであり、標準のLinuxユーティリティ(この例ではSHA-256を使用)を使用して実行することもできます。

yes "$pass$salt" | head -c 50M | sha256sum

独自の依存関係を取り入れることができる場合は、S2Kとカスタムスキームの両方に対する優れた代替策をリストした優れた回答のFuture Securityを聞くことを強くお勧めします。

3
forest

Argon2を依存関係として追加する価値はあります。または、最適化されたArgon2を使用できず、bcryptを使用して自分の足で撃つ方法をすべて回避できる場合は、bcryptを使用します。適切なオプションがない場合は、人間が自分のパスワードを選択できないように特別な配慮をしてください。

繰り返しハッシュによってエントロピーを失うことは、反復間でハッシュ出力を切り捨てたり、本当に悪いハッシュ関数を使用したりしない限り、気にする必要はありません。これは、出力が大きいセキュアな機能には問題ありません。 2つの異なるパスワードが一連のハッシュのマージにつながる場合のみ、何も失われません。つまり、偶発的な衝突があった場合のみです。

RNGを使用して新しい入力を生成する必要はまったくありません。暗号化ハッシュの出力は、ランダムに見える入力とランダムに見えない入力のどちらを使用しても同じようにランダムです。低速のソフトウェア実装を使用しなければならないときに、最適化されたハードウェア実装を使用できると、事態はさらに悪化する可能性があります。あなたは間違いなく実装に欠陥があるか、シードが64ビットの数値に減少した場合、事態を悪化させます。

特定の方法では、時間とメモリのトレードオフが許可される場合があります。 Argon2を含む パスワードハッシュコンペティション の一部の候補は、速度を半分にするだけの場合はメモリ要件を半分にできないように設計されています。 (Scryptはこのようなトレードオフを可能にし、その問題はより良いアルゴリズムを探す動機の1つでした。)計算時間を2倍にすることはメモリを節約する価値がないと思うかもしれませんが、結局はスループットが高くなり、消費電力、または安価またはより効率的な低メモリハードウェアを購入して、より多くの操作を並行して実行できる場合は、より少ないコスト。

考え出せるアルゴリズムが何であれ、せいぜい、せいぜいPBKDF2と競合するだけです。 (PBKDF2は素晴らしいものではありませんが、すでにハッシュ関数を持っている場合は、実装するのに十分簡単です。)

PBKDF2などを使用している場合は、SHA-3を使用しないでください。 SHA-3ハッシュはかなり効率的に計算できますが、CPUでは比較的低速です。パスワードクラッカーがより高速で効率的な実装を使用できる場合、それはパスワードクラッカーに有利です。実際には、SHA-2-512を使用したほうがよいでしょう。またはBlake2。

2
Future Security

新しい依存関係やサードパーティのコードを実際に含めることができない場合(そして、最初のステップは、この制限を元に戻すことです)、独自のアルゴリズムを作成するよりも、標準の吟味されたアルゴリズムを実装する方がはるかに優れています。次に、既知のセキュリティを備えたアルゴリズムを使用して、セキュリティの専門家に認められ、フィールドでの長年の使用を通じて実証されただけでなく、標準の実装またはテストベクトルに対してテストして、作成していないことを確認する機会を得ます。誤って最初の0バイトまでしかハッシュしないなど、セキュリティを台無しにする実装の誤り。実装が最も簡単でエラーが発生しにくいアルゴリズムはおそらくPBKDF2です。これは、ほとんどが暗号ハッシュプリミティブとソルトのランダム性のソースのみを必要とするため、すでに持っているようです。

0
Ben