web-dev-qa-db-ja.com

挑戦的な課題:クライアント側のパスワードハッシュとサーバー側のパスワード検証

ユーザーが特権情報にアクセスするためにログインする必要があるウェブサイトがあります。明らかにSSLを使用していますが、プレーンテキストのパスワードが誤ってサーバーログに記録されたり、管理者の目がさまようことも避けたいです。したがって、JavaScriptを使用してクライアント側のハッシュを実装したいと思います。

さらに、同じパスワードを持つユーザーのペアを明らかにしないようにしたいので、ユーザー固有のソルトを使用します。最後に、ランダムなチャレンジ(別名nonce)をミックスに追加して、盗聴者*が最終的なハッシュを新しい「パスワード」として使用できないようにします。パスワードのハッシュ化を開始する前に、ソルトとチャレンジを取得するためにWebサーバーへの追加の往復を行います。 *)はい、SSLを使用していますが、多層防御として、実装を可能な限り堅固にしたいと考えています。

特に挑戦は挑戦的です。私が知っている唯一の実現可能な実装は、最初に(bcrypt、scryptまたはPBKDF2を使用して)最終的なパスワードハッシュを計算し、次にチャレンジを使用して追加のsha256_hmacラウンドを実行することです。サーバー側では、データベースからパスワードハッシュをフェッチし、同じ追加のsha256_hmacを実行して結果を比較します。

ただし、上記のことはfullパスワードハッシュ計算はJavaScriptでクライアント側で実行する必要があることを意味します。チャレンジのハッシュは常に最後のステップであるべきだからです。従来の(?)iPhone 3Gでは、bcryptのラウンドが6回、またはPBKDF2-SHA256のラウンドが5000回しか実行できません。これは、許容できる最大遅延である2秒以内です。

質問1:現在、bcryptは少なくとも12ラウンド、PBKDF2-SHA256は少なくとも5000ラウンドである必要がありますか?だから私は5000ラウンドのPBKDF2-SHA256を選ぶべきですか?

質問2:プロセスの早い段階で(たとえば、一度ハッシュされたパスワードで)動作するチャレンジ/レスポンスメカニズムがあるので、bcrypt/PBKDF2を強化してウェブサーバーに任せることができますか?

質問#3:そのようなチャレンジ/レスポンスメカニズムが存在しないと仮定すると、チャレンジ/レスポンスの要件を破棄し、ユーザー固有のソルトクライアント側のみを適用して、サーバー側を完全に強化する方が良いでしょうか?その結果、チャレンジ/レスポンスメカニズムを使用するよりも全体的に強力なシステムになり、ラウンドが少なくなりますか?

編集:一般的なクライアント側のハッシュのセキュリティに関するコメントの長い軌跡を要約するには:一般的な意見は、追加された複雑さには価値がなく、サーバー側のコードの監査に力を注ぐ方が良いと思われます信頼できないスタッフのサーバー側アクセスを制限する。

14
Jason Smith

あなたはあなたの時間を無駄にし、不必要な複雑さを加えていると思います。あなたが与える理由は、この種のクライアント側のパスワードハッシュメカニズムを保証するのに十分ではないと思います。

代わりに、私はそれをシンプルに保つことをお勧めします。 SSL暗号化リンクを介してパスワードを送信します。セキュリティに関しては、シンプルが良いです。バグやミスが発生する可能性があるため、不必要な複雑さはセキュリティの敵です。

より現実的な脅威に対処する他のセキュリティタスクのためにエネルギーを節約してください。セキュリティの向上に費やすことができる時間とエネルギー、予算は限られています。費用対効果が最大になる場所に投資するのが最善です(投資を考慮すれば、セキュリティが最大に向上します)。システムを強化してセキュリティをさらに向上させる方法は他にもあると思います。

サーバー側のコードがパスワードを適切に処理しているかどうかが心配な場合は、そのコードを慎重に確認してください。コードは非常に小さなコードチャンクに含める必要があります。これは、たとえばサーバーがクリアテキストのパスワードをログに記録するなどのリスクに対処する必要があります。パスワードチェックに関連するコードのすべての行を読み取るか、パスワードを読み取るだけです。最初に行うことは、パスワードを適切にハッシュして、パスワードの有効性を確認し、trueまたはfalseを返すことだけを確認してください。システムが適切に設計されている場合、コードレビューで確認するのは非常に簡単です。コードがうまく設計されていない場合は、おそらくそれを修正する良い機会でしょう。

11
D.W.

まだ行っていない場合は、SRPを調べてください。チャレンジ/レスポンス型システムが必要な場合は、すべての要件を満たしている必要があります。

http://en.wikipedia.org/wiki/Secure_Remote_Password_protocol

6
broadway

自家製のプロトコルには注意が必要です。また、クライアント側のハッシュベースの認証プロトコルにも注意が必要です。あなたの最善の策は、このプロトコルに対する攻撃の NTLM Authentication およびLARGE NUMBERを研究することです。 NTLMの弱いnonceの脆弱性 など。

(SRPは悪くありません、SRP-TLSはかなりクールに見えます。)

4
rook
  1. いいえ、まだ小さすぎます。 OWASPパスワードストレージチートシートでは、2012年に64,000 PBKDF2の反復を推奨し、2年ごとに2倍にする(https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet)。

  2. 上記の他の回答を参照してください。

  3. クライアント側でハッシュを実行するオプション(たとえば、2,000 PBKDF2_SHA-1ラウンド)があり、その結果がサーバーに到達したら、別の大きなハッシュセット(たとえば、300,000ラウンドのPBKDF2_SHA- 512)、その最終値を比較します。

データベースには、最終的なdouble-PBKDF2値のみが格納されます。

Webログファイルや脆弱なSSLセッションで中間の単一PBKDF2値が使用されています。その中間値は確かに多く、最終値よりはるかに弱いですが、それでもクリアテキストよりもかなり強力です。

また、パスワードを変更したり、新しいパスワードを選択したりするときにユーザーが提案するパスワードを、いくつかのルールを使用して通常のクラッキング辞書と照合して確認する必要があります(大文字と小文字を区別するために両方を小文字にし、単語の後に1から1000までの数字を追加し、単語の後に日付を追加します) 、基本的な1337が翻訳などを話します)、「強力な」パスワード「P @ $$ w0rd」(大文字、小文字、記号、数字-8文字の長さで、非常に強力である必要があります)が表示されないようにします。