web-dev-qa-db-ja.com

クライアント側のパスワードハッシュ

編集:目標をより強調するために更新されました-ユーザーの安心感であり、セキュリティを強化するものではありません。

パスワードのクライアント側ハッシュについてここでいくつかの議論を読んだ後も、私は特定の状況でそれを使用するのが大丈夫なのかどうかまだ疑問に思っています。

具体的には、クライアントが欲しい-a Javaプログラム-PBKDF2のようなものを使用してパスワードをハッシュし、saltとして電子メールアドレスとの組み合わせを使用する定数のアプリケーション固有チャンクのバイト。ハッシュは認証では再現可能であるが、(文字通りのパスワードを発見するための)リバースエンジニアリング攻撃に対して脆弱でなく、サーバーデータが危険にさらされています。

目標:

クライアント側のハッシュは、たとえそれがストレージでハッシュされているという保証があったとしても、リテラルパスワードがサーバーによって受信されないというユーザーの安心のためです。もう1つの副次的な利点(またはおそらく法的責任?)は、反復PBKDF2または類似のハッシュコストがクライアントにあることです。

環境特性は:

  1. すべてのクライアント/サーバー通信は暗号化されています。
  2. メッセージの再生は許可されていません。すなわち。クライアントから送信されたハッシュは、盗聴者がパスワードとして効果的に使用することはできません。
  3. IPを一時的に禁止およびブラックリストに登録すると、短時間で複数のサインインが失敗する可能性があります。これは、ユーザーアカウントごとでも、システム全体でもかまいません。

懸念事項:

  1. 「手製の認証スキームを考案することは避けてください。」
  2. (同一の)追加のバイトがソルトにスローされるため、生成されるハッシュがこのアプリケーションに固有のものである場合でも、ソルトは各ユーザーにとって確定的です。これは悪いですか?
  3. サーバー側の認証は、大幅な遅延なしに、ハッシュコストなしで行われます。これにより、分散型ブルートフォース認証攻撃に対する脆弱性が増加しますか?
  4. 不正なクライアントは、自分のアカウントに弱いハッシュを提供できます。実際、あまり心配していません。
  5. サーバーは、格納する前にクライアントハッシュを再ハッシュする必要がありますか?

考え?

31
Foy Stip

クライアント側でのハッシュは、パスワードハッシュが解決しようとする主な問題を解決しません-攻撃者がハッシュされたパスワードデータベースにアクセスした場合に何が起こるか。クライアントから送信された(ハッシュ化された)パスワードはそのままデータベースに保存されるため、このような攻撃者は、データベースからハッシュ化されたパスワードをそのままサーバーに送信して、すべてのユーザーになりすますことができます。

一方、クライアント側のハッシュは、サーバーがパスワードを知らないことをユーザーに保証する保証するという点で素晴らしいです。これは、ユーザーは複数のサービスに同じパスワードを使用します(ほとんどのユーザーと同じです)。

これに対する可能な解決策は、クライアント側とサーバー側の両方でハッシュすることです。それでも、重いPBKDF2操作をクライアントにオフロードし、サーバー側で(クライアント側のPBKDF2ハッシュされたパスワードで)単一のハッシュ操作を実行できます。クライアントのPBKDF2は辞書攻撃を防ぎ、サーバー側での単一のハッシュ操作は、盗まれたデータベースからハッシュされたパスワードをそのまま使用することを防ぎます。

45

クライアント側のハッシュが価値のある時間はほとんどありません。そのような状況の1つは、ハッシュプロセスが計算集約的である場合です。これは、PBKDF2の場合になる場合があります。

懸念に対処する:

  1. また、インターネットで見つけた暗号についての未検証の提案も避けてください。 (免責事項:私はBruce Schneierではありません。)
  2. 確定的なソルトは問題ではありません。ソルトの実際の要件は、ユーザーごとに固有であることだけです。 saltの本当の目的は、データベースのセキュリティが侵害された場合に、1つのパスワードの総当たり攻撃がすべてのパスワードの総当たり攻撃になるのを防ぐことです。ハッシュされたパスワードのすぐ横にあるランダムなソルトをデータベースに保存する場合でも、各ユーザーが異なる場合は、この目標に到達します。
  3. 上で述べたように、PBKDF2は、ハッシュの計算難易度を任意に決定できるので、Niceです。 cを選択すると、最新のハードウェアでの単一のハッシュに数秒かかるため、APIレベルのブルートフォース攻撃のリスクを効果的に排除できます。 (もちろん、クライアントはログイン時にそれほど長い遅延を享受しないかもしれません。)
  4. ユーザーは単純なパスワードを選択できます-彼らは自分自身を傷つけるだけです。このリスクを排除したい場合は、パスワードが暗号化されたチャネルを経由する場合、サーバーに最初にハッシュを生成させる必要があります。
  5. はい、あなたもこれらを独自に塩漬けにする必要があります。データベースが侵害された場合、攻撃者がシステム上の任意のユーザーとして直接認証できるような情報を攻撃者が取得しないようにする必要があります。ここでの注意点の1つは、サーバー側のハッシュをクライアント側のハッシュのように計算集約型にしたくない場合です。サーバー側のハッシュに多大な労力がかかる場合、CPUを使い果たすサービス拒否攻撃のベクトルに身を任せます-攻撃者は、Torを介して空のパスワード認証の試行をスパムするだけです。詐欺的で、最終的には圧倒されるサーバーを残してしまいます。
12
Motoma

クライアント側でパスワードをハッシュすると、結果が何であれ、ISパスワードなので、実際のセキュリティは得られません。プレーンテキストのパスワードを明らかにしたハッキン​​グや情報漏洩代わりに、実際のパスワードであるハッシュされたパスワードが表示されます。

これをゼロ知識認証スキームと混同しないでください。メッセージの交換により、クライアントは実際にパスワードを送信せずに実際のパスワードを知っていることが証明されます。

9
ddyer

独自の暗号化プロトコルを発明しようとしているようです。あなたのアプローチの説明から、これを安全な方法で行うための背景があるようには思えません。独自のプロトコルを作成する代わりに、既存のプロトコルを使用することを強くお勧めします。

まず、回避している脅威モデルが明確ではありません。あなたは「リバースエンジニアリング攻撃」と呼ばれるものを引用しますが、これは実際の定義や意味はありません。

次に、ソルトの目的とその生成のためのベストプラクティスについての理解が不足しているようです。塩は秘密にしておく必要はありません。新しい認証トークンごとにCSPRNGから一意のソルトを生成できます(変更する必要があります)。固定されたアプリケーション固有のソルトは「peppers」と呼ばれることもあり、その使用をサポートまたは奨励する暗号化文献については知りません。

第3に、PBKDF2は問題ありませんが、真剣に se BCrypt です。 BCryptはこのために設計され、広く使用されています。優れたBCrypt実装は、塩の生成と作業係数の調整/自動検出を処理します。 PBKDF2を使用するには、これらを自分で実装する必要があり、ほぼ間違いなく間違いを犯します。

第四に、あなたがやろうとしているように見えるものに対して既存のアプローチがあります。ゼロ知識認証は [〜#〜] srp [〜#〜] で実行できます。ユーザーのパスワードがネットワーク経由で送信されることは決してなく、真ん中の人は自分自身を認証するために役立つ情報を盗聴することはできません。ただし、正しく実装することは明らかに困難であり、実装する既存のライブラリは多くないため、問題が実際にどれほど困難であるかがわかります。

要するに、独自の暗号を発明しないでください。広く実装され、時間のテストに耐えてきたソリューションとプロトコルを使用します。

7
Stephen Touset

クライアントでのハッシュは、状況や理由によっては良い考えですが、 "ユーザーの安心"をそれらの1つにすることはしません。私はユーザーが調和のとれた心の中にいて、宇宙と一体であることはすべてですが、私は誘導する方法を促進するという考えに疑問を感じます複数のサイトで同じパスワードを再利用するユーザー。

クライアント側のハッシュの良い例は、いくつかの「パスワードセーフ」が機能する方法です。これらは、ユーザーの「マスターパスワード」をサイト名と一緒にハッシュすることにより、サイト固有のパスワードを計算します。これにより、どこでも常に同じパスワードを使用するという使いやすさのほとんどが得られますが、実際にはマスターパスワードを数十の異なるサイトに与えることはありません。ただし、これが機能するのは、パスワード導出アルゴリズムが汎用的で、変更されていない場合のみです。これは、サイト自体からのアプレットよりもWebブラウザ拡張で対処するほうがはるかに優れているようです(サイト固有のデータで同じパスワード導出アルゴリズムを使用するアプレットを使用するには、すべてのサイトが連携する必要があります)。

クライアント側のパスワードハッシュのもう1つの良いケースは、slow hashを使用する場合です(コピーを取得できる攻撃者がパスワードの解読を困難にするため)ハッシュされたパスワードのデータベースの);クライアントがコストをオフロードしようとするのは魅力的です。なぜなら、クライアントが接続したいときは、ほとんどアイドル状態であり、積極的に接続に関心があるからです。ただし、低速ハッシュは、攻撃者と防御者の間のarms raceです。 Javaを使用すると、通常の3倍の速度で)速度が低下し、一部のクライアントシステムは非常に弱くなる場合があります(たとえば、安価なスマートフォンや10年前のコンピューター)。対戦相手が戦車を持ち込むバトルに入る前に、アサルトライフルの代わりに剣を使用する)。

しかし、ユーザーが望むことは、サイトによるずさんなストレージプロシージャからパスワードを保護することである場合、正しい方法はサイトごとに異なるパスワードを選択するです。 (個人的には、パスワードのファイルを保管しており、すべてのパスワードはランダムに生成されます。)

6
Thomas Pornin

Googleの従業員がTLS-OBCと呼ばれる同様の何かに取り組んでいます。このRFCドラフトにより、クライアントはパスワードをハッシュしてTLSセッションにバインドできます。

具体的には、このWebサイトに興味がある可能性があります http://www.browserauth.net/Origin-bound-certificates

強力なユーザー認証に関するこのリンク http://www.browserauth.net/strong-user-authentication

::更新

OBCおよびおそらく他の1つは、FIDO認証標準に統合されました。

4

パスワードハッシュの主な目的は、ユーザー以外の誰もがパスワードを学習できないようにすることです。人々はそれらを再利用します、そして、彼らは覚えられれば、通常超強力ではありません。これが、高速ハッシュの代わりに低速ハッシュ(PBKDF2、Bcrypt、Scrypt、Argon2など)に悩まされる理由です。アプリケーションには何の利点もありませんが、ユーザーのパスワードをよりよく保護します。 サーバーにデータベースに保存する前に、何でも入ってくるものをハッシュさせることの副次的な利点は、データベースを危険にさらす人がどの値でもログインできないことです彼らは見つけた(彼らは最初に彼らをクラックしなければならない)。

両方のメリットを維持したいと考えています。そのためには、サーバーとクライアントをハッシュする必要があると主張します

なぜサーバーにいるのですか?
データベースを取得した攻撃者が取得したデータを使用してログインできないようにします。クライアントがすでに低速ハッシュを実行している場合、これはいくつかの安全なハッシュアルゴリズム(SHA-3やBLAKE2など)の単一ラウンドである可能性があります。

なぜクライアントにいるのですか?

  1. 透明性
    企業がハッキングされたときはいつでも、パスワードがどのようにハッシュされたのかについて、彼らが私たちに教えてくれることを願っています。プレーンテキストを保存したり、高速アルゴリズムを使用したり、ソルトを行わない場所などがまだあります。クライアント側でハッシュを行うことで、興味のある人はそれがどのように行われているかを確認し、防止できます これらのような質問 =。私の母はそれをチェックしませんが、私の母はWebサイトのTLSでハートビートをチェックしません。「倫理的ハッカー」またはホワイトハッカーがチェックします。
  2. 侵害の検出
    よくある議論は、「サーバーが侵害された場合、攻撃者はパスワードのハッシュを担当するJavaScriptコードを削除し、攻撃者がとにかく平文を取得できるようにする」というものです。この議論はウェブサイトに対してのみ有効ですが、人々は通常それについて言及するのに失敗し、その結果、誰もアプリケーションのクライアント側をハッシュしません。彼らがさらに忘れているのは、クライアント側のハッシュが一般的である場合、セキュリティ研究者はそれを使用し始めることができるということです:重要なWebサイトをスキャンしてハッシュがまだあるかどうかを確認する人々がいますクライアント側のハッシュ(最初にクライアント側のハッシュを実行するという仮定の場合))、およびログイン時に警告するのと同じように、削除された場合に警告するブラウザー拡張機能(または組み込み機能)が存在する可能性がありますhttpページのフォーム。
  3. 標準を改善する
    これで全員の実装を確認できるようになったので、誰が最も長く、誰が最も優れているかについての議論があります。この議論は間違いなく悪い人にもっと良いことをするように圧力をかけます、そしてそれはおそらく標準化にもつながります。 <input type=password hash=v1>のようにパスワード入力要素にパラメータを追加するだけで、すべてのハッシュが実行されれば非常に便利です(ドメイン名とユーザー名フィールドをソルトしますが、この提案はこの回答の範囲を超えています)。
  4. サーバーをオフロードする
    サーバーで非常に遅いハッシュを実行するリスクは、攻撃者がサービス拒否攻撃にそれを使用できることです。サーバーが各ログイン試行を処理するために2秒を必要とする場合、攻撃者は攻撃しようとすることに大きな利点がありますそれを下に。クライアントで低速ハッシュを実行することで(CPUは99%の時間使用されず、ほとんどの人が1日に数回以上ログインするようなものではありません)、サーバーの負荷を軽減し、より遅いハッシュを選択できるようにします。攻撃者がサーバーをダウンさせる危険を冒すことなく。
  5. 秘密のスヌーピングはありません
    従業員は、データベースをハッシュしても、ハッシュされて保存される前にパスワードを傍受する可能性があります(TLS終了ポイントでログを記録するか、追加のコードをインストールすることにより)。酸っぱい従業員、またはユーザーのパスワードを見るのがおかしいと思うかもしれないアプリケーションを作成している10代の若者でさえ十分な話があります(私はその1つでした)。
  6. プレーンテキストのメールはありません
    サーバーにパスワードがない場合、サーバーは「登録していただきありがとうございます。ユーザー名とパスワードはxxxです」のようなメールを送信できません。電子メールは一般的に安全ではないと考えられていますが、これを行うWebサイトはまだあります。
  7. 偶発的な暴露なし
    最近、パスワードが誤ってログファイルに書き込まれたという事件がありました。関連性はないと思うので、会社名については触れませんが、専用のセキュリティチームとすべてを備えた大規模なハイテク企業でした。このような事故は起こります。さらに、別のシステムがTLS終了を実行し、要求のプレーンテキストを他のシステムに送信する多くのネットワークで露出があり、どのネットワークボックスでもパスワードを確認できます(GoogleはNSA内部ネットワークにインターセプトがあること。これは、クライアント側のハッシュを実行した場合、問題ははるかに少なくなります(露出がはるかに少なくなります)。
  8. 感染の影響を軽減
    TLSのバグなど、何らかの理由で安全な伝送チャネルが失敗した場合、攻撃者は元のパスワードではなくハッシュのみを観察できるため、影響は軽減されます。これは、誰かが暗号化されたストリームを数年後に解読できる場合にも当てはまります。たとえば、RC4が数年以上前に壊れていることがわかっているためです。
  9. 何故なの?
    サーバーでクイックハッシュを追加して(最初のセクションで述べた2次的な利点を得るため)、しないでください理由は考えられません。段落)。理由の1つだけが説得力があると思う場合でも、それでも改善されます。

[〜#〜]よくある質問[〜#〜]

クライアント側のハッシュが標準ではない唯一の理由は、他の誰もそうしないからです。誰かがそれを提案するときはいつでも、誰もが「それなら、なぜそれをすでにやらないのか?理由があるに違いない!」と考えます。そして、利点を疑問視し始めるか、または非論理的な理由を発明します。上記の理由でまだ十分ではない場合は、これまでに聞いた質問のいくつかを否定してみましょう。

  • 「しかし、攻撃者はハッシュを担当するコードを削除するだけです!」これはWebアプリケーションにのみ適用されます。通常のアプリケーション(どのモバイルアプリケーションの中でも)ではこの問題は発生しません。
  • 「しかし、私のケースはWebアプリケーションに適用されます!」クライアント側のハッシュがWebアプリケーションで一般的である場合、私たちはこれのチェックを構築します。人々はブラウザー拡張機能を構築し、ハッシュがまだあるかどうかを確認するためにWebサイトをスキャンし、突然なくなった場合にアラームを鳴らすことができます。標準化もあるかもしれません。 Webアプリケーションの場合でも、上記のポイントのすべてはまだ保持されます。
  • 「しかし、(クライアント側のハッシュの)結果がISパスワードです!」なんでも質問させてください。ログインデータベースが危険にさらされている場合、本当に攻撃者は引き続きアプリケーションにログインしてすべてのデータを取得する必要がありますか?ほとんどのシステムの多層防御は実際にはそれほど良くありませんが、たとえそうであっても、アドバイスは追加のサーバー上のクイックハッシュ。
  • 「しかし、あなたはハッシュのセキュリティに頼るのではなく、パスワードマネージャを使うべきです!」私は同意します、それは理想的です。誰もが使用する、パスワードマネージャーとスマートカードを使用した、あらゆる場所での2要素認証...ええ、その日が来ると、もはやパスワードハッシュは必要なくなります。前述の副次的な利点のためにサーバーで高速ハッシュを実行する必要がありますが、パスワードを再利用する人がいないため、低速ハッシュアルゴリズムとクライアント側ハッシュの実行を停止できます。
  • 「しかし、ユーザーにセキュリティを任せるべきではありません!」彼らはすでにセキュリティを担当しています。123456をパスワードとしていつでも選択できます(または、ばかげた要件がある場合でも、「Bailey2009!」を実行できます)。 TLS接続にキーを公開して、セキュリティを無効にすることもできます。ユーザーは、必要に応じて、実装したセキュリティを常に混乱させることができます。
  • 「でも、どうやってハッシュを塩漬けにするの?」ユーザー名フィールド。ユーザー名フィールドと同じように、saltは秘密ではなく、唯一のものです。
1
Luc