web-dev-qa-db-ja.com

クライアント側のハッシュは、遅いハッシュでサービス拒否のリスクを減らすことができますか?

検証する必要がある(ただしプレーンテキストとしては使用しない)ユーザーのパスワードを保存する場合、最新の状態は次のとおりです。

  1. パスワードをハッシュする
  2. 塩を使う
  3. 遅いハッシュ関数を使用してください-bcrypt、scryptなど。

これは、パスワードデータベースを盗んだ攻撃者に対して可能な限り最高の保護を提供します。フィッシング、マルウェア、パスワードの再利用などの他の問題は解決しません。

しかし、残りの1つの問題があります。低速ハッシュ関数により、サービス拒否 攻撃。単一の要求が大量のCPUを消費するため、比較的少ない数の同時要求でDOSが可能になり、IPスロットリングなどの防御を使用することが困難になります。

ブラウザーでのJavaScriptのパフォーマンスの向上を考えると、ブラウザーでこれを実行することは理にかなっています。ここでは、サイトがSSLを使用していることを前提としているため、JavaScriptは安全に配信されます。 SSLを使用していない場合は、低速のハッシュ関数を使用することが優先されることはまずありません。 bcryptには少なくとも1つ JavaScript実装 があります。しかし、これを簡単な方法で使用すると、2つの問題が発生します。

  1. クライアントはサーバーからソルトをフェッチする必要があります。これにより、ログイン時に遅延が発生し、注意しない限り、特定のユーザーアカウントが存在するかどうかが明らかになる可能性があります。
  2. ハッシュが純粋にクライアントで行われる場合、ハッシュを格納することの利点は失われます。パスワードハッシュを盗んだ攻撃者は、ハッシュを使用して単純にログインできます。

しかし、私はそれらの問題の両方に受け入れられる解決策があると思います:

  1. ソルトはhash(server_salt + user_name)として生成できます。ここで、server_saltはサーバーに固有の乱数で、パブリックで、すべてのユーザーで同じです。結果のハッシュには、saltの必要なプロパティがあるようです。
  2. サーバーは、受信したハッシュに対して単一の高速なハッシュ操作を実行する必要があります。例として:サーバーはSHA-256(bcrypt(salt、password))を保存します。クライアントはbcrypt(salt、password)を送信し、サーバーはSHA-256を適用してハッシュをチェックします。これにより、攻撃者は高速のオフラインブルートフォース攻撃を実行できません。パスワードには2 ^ 50または2 ^ 60程度のエントロピーの制限があるため、SHA-256(password)のブルートフォースを高速に実行できます。しかし、128ビットのbcrypt(salt、password)にはエントロピーまたは2 ^ 128があるため、ブルートフォースを簡単に実行することはできません。

それで、これは合理的で安全なアプローチですか?

「自分の暗号を使わない」という一般的なアドバイスを知っています。ただし、この場合は、既成の暗号では解決できない問題を解決しようとしています。いくつかの基本的な信頼性について、これは John Steven (この分野で認められた専門家)によって検討されており、「簡単な」分析からの肯定的な結果が得られています。

29
paj28

Servername + usernameをsalt(またはそのハッシュ)として使用するのは理想的ではありません。これは、パスワードを変更したときに、saltの再利用につながるためです(名前を保持し、同じサーバーと通信するため)。別の方法は、準備ステップとしてサーバーからソルトを取得することです。これは、追加のクライアントサーバーラウンドトリップを意味し、サーバーは、特定のユーザー名が存在するかどうかを非表示にするのがより困難であることも意味します(ただし、実際にはそれほど重要ではありません)。

あなたが説明するのは、よく知られているアイデアであり、通常serverliefと呼ばれます。これは、説明する方法で任意のパスワードハッシュ関数に適用できます。

  • クライアントはソルトを取得(または計算)します。
  • クライアントは低速ソルトハッシュ値[〜#〜] v [〜#〜]を計算し、それをパスワードとして送信します。
  • サーバーは、いくつかの高速ハッシュ関数hh(V)を格納し、それを使用してを検証します[〜#〜] v [〜#〜]クライアントからの値。

これは安全です。主な欠点は、遅いハッシュがクライアントの速度で行われることです。そのため、反復回数を減らす必要があるかもしれません。クライアントが計算能力が弱い場合は、JavaScriptが関係する場合のように、かなり低くなる可能性があります。システムがそれほど最近ではないスマートフォンのブラウザーで動作する必要がある場合、反復回数はサーバーで実行できる回数よりも10倍から100倍小さくする必要があり、ブルートフォース(攻撃者がサーバーに保存されているハッシュ値を盗む場合)。

これはトレードオフです:負荷の高いサーバーはクライアントでオフロードするため、負荷がかかることなく、より高い反復カウントを使用できます。ただし、クライアントが弱いため、反復回数を減らす必要があります。これは、通常、オフロードによって増加した数よりもはるかに多くなります。これは、その構築に努力する価値がないことを意味します。通常。


もちろん、クライアントが計算能力が高い場合、たとえばこれはゲーム機のネイティブコードアプリケーションであり、サーバーの救済は良い考えであり、あなたがそれを説明する方法のように見えます。

別の可能性としては、作業を別のサードパーティシステム(例:他のクライアント(接続済み):これは安全に実行できますifハッシュ関数に必要な数学的構造が含まれている場合。そのようなオフロードはdelegationとして知られています。私の知る限りでは、委任は、現在の候補の1つである Makwaspecification を参照)と呼ばれる単一のパスワードハッシュ関数によってのみ提供されます Password Hashing競争

23
Tom Leek

このアプローチの最大の懸念は、サーバーからではなくユーザーのWebブラウザーに重要であると判断したセキュリティ手順を移動することです。通常、すべてが期待どおりに機能するはずですが、送信前にパスワードが実際にbcryptでハッシュされたことを確認する実際の方法はありません。したがって、クライアント側のJavaScriptが変更された場合でも、サーバー上で「123456」のSHA256ハッシュのみが残る可能性があります。

確かに、クライアントから送信されたデータの形式をチェックして、bcryptでハッシュされたように見えることを確認できますが、目的の操作が完了したかどうかはわかりません。

これは理想的なセキュリティモデルではありませんが、それでも、このシステムに対する脅威は依然としてかなり管理可能だと思います。また、ハッシュを行わない、またはプレーンMD5を使用してハッシュを行うサイトよりも先を行くでしょう。

1
PwdRsch