web-dev-qa-db-ja.com

クライアント側でパスワードをハッシュする価値はありますか

ログインシステムを適切に配置する場合、指定されたパスワードのMD5とサーバー側のユーザーテーブルの値を常に比較します。

しかし、私の友人は、「クリア」なパスワードはネットワークソフトウェアによって盗聴される可能性があると私に言った。

だから私の質問は次のとおりです。クライアント側でパスワードをハッシュすることは良い考えですか?サーバー側でハッシュするよりも良いですか?

117
Zakaria

基本的に、あなたの友人は正しいです。しかし、単純にクライアント側でパスワードをハッシュ化することは、サーバーにプレーンテキストとして送信するよりもjustよりも優れています。プレーンテキストパスワードをリッスンできる人は、確かにハッシュ化されたパスワードをリッスンし、これらのキャプチャされたハッシュを使用してサーバーに対して認証することができます。

この問題については、通常、クライアントがパスワードと一緒にハッシュされるランダムなビットを選択できるようにすることで、このようなリプレイ攻撃が機能しないことを確認するために、より安全な認証プロトコルが多くのフープをジャンプします、また平文でサーバーに送信します。

サーバー上:

  • 数ビットのランダムを生成します
  • これらのビットをクリアテキストでクライアントに送信します

クライアントで:

  • いくつかのランダムなビットを生成します
  • パスワード、サーバーのランダムビット、クライアントのランダムビットを連結する
  • 上記のハッシュを生成する
  • ランダムデータ(クリアテキスト)を送信し、サーバーにハッシュします。

サーバーは、クライアントのランダムなビットだけでなく、クライアント自身のランダムな情報も知っているため(クリアテキストとして取得)、基本的に同じ変換を実行できます。このプロトコルは、両方の当事者が毎回異なる「ノイズビット」を生成する限り、この会話を聞いている人が記録された情報を使用して誤って認証するために後で情報を使用できないことを確認します(非常に弱いアルゴリズムが使用されない限り...)、ハンドシェイクが実行されます。

編集これらはすべてエラーが発生しやすく、面倒であり、正しく理解するのがやや困難です(読み取り:安全)。可能であれば、知識のある人によって既に書かれた認証プロトコル実装の使用を検討してください(私とは異なります!上記は私が少し前に読んだ本の記憶からのみです)。

103
Dirk

まず第一に、これは[〜#〜] not [〜#〜]アプリケーションのセキュリティを向上させます(webappであると仮定)。

SSLを使用(または実際には一般的にSSLと呼ばれるTLS)、それほど高価ではありません(回避方法を見つけて最低賃金で乗算するために使用している時間を測定し、購入します)証明書がほぼ常に勝ちます)。

これの理由は簡単です。 TLSは、暗号化で非常に大きな問題(自己署名ではなく、購入した証明書で使用する場合)を解決します。通信しているサーバーが、通信していると思うサーバーを知るにはどうすればよいですか? TLS証明書とは、「ブラウザによって信頼されている認証局である私は、[url]のWebサイトにこの公開キーがあり、サーバーのみが知っている(秘密キー)誰かがそれを変更した場合、あなたが見ることができるように、私は文書全体に署名をしました」。

TLSなしでは、暗号化は無意味になります。コーヒーショップで隣に座っていると、ラップトップ/スマートフォンに自分がサーバーであり、MiTM(Man in The Middle)であると思わせるからです。 TLSを使用すると、あなたのサイトに一致する認証局の署名付き証明書がないため、ラップトップ/スマートフォンは「信頼できない接続」と叫びます。 (暗号化と認証)。

免責事項:ユーザーはこれらの警告を右クリックする傾向があります:「信頼できない接続?何?子猫の写真が欲しいだけです!例外を追加ClickConfirmClickYAY!Kittens!」

ただし、実際に証明書を購入したくない場合は、まだクライアント側のJavaScriptハッシュを実装する(およびそのためにスタンフォードライブラリ(SJCL)を使用する)NEVER IMPLEMENT CRYPTO YOURSELF )。

どうして?パスワードの再利用! HTTPSを使用せずに、セッションCookieを盗むことができます(これにより、あなたのサーバーになりすますことができます)(firesheepを参照)。ただし、ログインページにjavascriptを追加して、送信する前にパスワードをハッシュします(SHA256を使用するか、SHA256を使用し、生成した公開キーを送信し、それを使用してハッシュされたパスワードを暗号化します)。ソルトは使用できません。これを使用して)、ハッシュ/暗号化されたパスワードをサーバーに送信します。 ソルトを使用してサーバー上のハッシュを再ハッシュし、データベースに保存されているものと比較します(次のようにパスワードを保存します:

(SHA256(SHA256(password)+salt))

(データベースにもソルトをプレーンテキストとして保存します))。そして、次のようにパスワードを送信します。

RSA_With_Public_Key(SHA256(password))

次のようにパスワードを確認します。

if SHA256(RSA_With_Private_Key(SHA256(sent_password))+salt_for_username) == stored_pass: login = ok

[〜#〜] if [〜#〜]誰かがあなたのクライアントをスニッフィングしているので、彼らはあなたのクライアントとしてログインできます(セッションハイジャック)が、彼らは[〜#〜 ] never [〜#〜]プレーンテキストのパスワードを参照してください(ただし、javascriptを変更しない限り、スターバックスのハッカーはこの方法を知らないか、興味があるでしょう)。したがって、webappにはアクセスできますが、メール/ facebook /など。 (ユーザーが同じパスワードを使用する可能性が高いため)。 (電子メールアドレスは、ログイン名であるか、webappのプロファイル/設定にあります)。

これについて心配する必要はないかもしれません-ダークがパスワードをハッシュしたとしても、悪意のあるユーザーがネットワーク上にいる可能性があり、ハッシュが送信されるのを確認し、同じハッシュを自分で送信できます。

悪意のあるユーザーがパスワードを知らないようにするという点でわずかに優れていますが、ログインできるため(または潜在的に 元のパスワードを再構築 )、それはそれほど役に立ちません。

一般に、ユーザーのパスワードとデータの安全性に不安がある場合(そして、そうするべきです!)、安全なSSLサーバーを使用することをお勧めします。なんらかの理由でこれが心配でない場合は、ハッシュを気にする必要はありません。それはただ 隠蔽によるセキュリティ です。


2014年8月編集:Googleはウェブサイトをより強力に どこでもHTTPSに切り替える にプッシュしています。ネットワークスニッフィング攻撃を防ぐ唯一の方法。送信されたデータを難読化しようとすると、専用の攻撃者が妨害されるのではなく、妨害されるだけであり、開発者に危険な誤った安心感を与える可能性があります。

21
dimo414

実際、この場合、クライアント側のハッシュはより安全であることに同意しません。安全性は低いと思います。

実際のパスワード(または暗号化されたパスワード)とは対照的に、データベースにパスワードのハッシュを保存する全体のポイントは、ハッシュから元のパスワードを取得することは数学的に不可能です(ただし、衝突を取得することは理論的には可能です)ハッシュ入力、その難易度はハッシュアルゴリズムのセキュリティ強度に依存します)。ここで考えられる攻撃ベクトルは、潜在的な攻撃者が何らかの方法でパスワードストレージデータベースを侵害した場合、ユーザーの元のパスワードを取得できないことです。

認証メカニズムがパスワードのハッシュを送信する場合、このセキュリティ侵害シナリオでは、攻撃者は実際のパスワードを知る必要はありません-持っているハッシュを送信するだけで、特定のユーザーのアカウントにアクセスできます。そして拡張により、システム全体。これは、そもそもハッシュされたパスワードを保存するポイントを完全に無効にします!

本当に安全な方法は、クライアントにワンタイム公開キーを送信してパスワードを暗号化してから、サーバー側で復号化して再ハッシュすることです。

ところで、この種の質問は、おそらくセキュリティStackExchangeでより専門的な回答を得るでしょう。

9
Kidburla

クライアント側のハッシュを使用できますが、サーバー側のソルトは使用できません。

リンクをご覧ください クライアント側のパスワード暗号化

3
SmAxlL

サードパーティに対してパスワードを安全に保つことは、それだけではないことに注意してください。

プライバシーが関係するとすぐに(そして最近ではない場合、最近では?)yoパスワードを知りたくない。持っていないものを悪用したり漏らしたりすることはできませんhaveなので、平文のパスワードを見たことがない場合は、あなたとクライアントの両方がよりよく眠れるようになります。

したがって、クライアント側のハッシュ/暗号化は理にかなっています。

2
Raphael

最近、GitHubとTwitterの両方が、パスワードが内部ログに保存されることを発表しました。バグレポートやsplunkなどへの道を見つけた他のログで不注意にこれを起こしてしまいました。Twitterの場合、トランプのパスワードがログにある場合、管理者が「見る」のは大したことです。管理者はあまり使い道がないので大したことです。管理者に関係なく、パスワードが表示されるのを見るのは好きではありません。

質問は、セキュリティのためにクライアント側でハッシュを行うべきかどうかですが、パスワードが最終的にハッシュされてサーバー側で比較される前にパスワードを保護して、何らかの方法でログに記録されないようにする方法です。

暗号化は悪いアイデアではありません。開発者は少なくともいくつかの問題を回避する必要があり、パスワードがログに記録された場合は、暗号化キーを変更し、元のキーを破壊するだけで、データは役に立たなくなります。キーを毎晩回転させると、ウィンドウが大幅に減少する可能性があります。

ユーザーレコードのハッシュをハッシュすることもできます。漏洩したパスワードは、ハッシュ化されたプレーンテキストパスワードです。サーバーはハッシュのハッシュバージョンを保存します。ハッシュがパスワードになることは確かですが、写真の記憶がない限り、60文字のbcyrptを覚えることはできません。ユーザー名でソルトします。ログインプロセス中に(ユーザーレコードが存在することを公開せずに)ユーザーに関する情報を収集できる場合は、サイト間で共有できないより堅牢なハッシュを作成することもできます。真ん中の人は、サイト間でキャプチャしたハッシュをカットアンドペーストすることはできません。

サーバーに送信されないcookieと組み合わせると、何かにアクセスする可能性があります。最初のリクエストで、キー付きのCookieをクライアントに送信してから、Cookieがログインサービスに戻らないようにして、ログに記録される可能性を少なくします。キーをセッションストアに保存し、ログイン直後またはセッションの有効期限が切れたときにキーを削除します。これにはJWTユーザーの状態が必要ですが、単にnosqlサービスを使用することもできます。

そのため、管理者は、splunkまたはバグ報告ツールでこれらのハッシュ化され暗号化されたパスワードのいずれかに遭遇します。暗号化キーを見つけることができなくなったため、彼らが役に立たないはずであり、たとえ見つけたとしても、ハッシュをブルートフォースする必要があります。さらに、エンドユーザーは平文を何も送信しなかったため、少なくとも真ん中の人は苦労し、別のサイトに移動してログインすることはできません。

1
Eric Twilegar

私は最近これについて多くの作業を行ってきましたが、IRLにはクライアントサイドハッシュ/symmetric暗号化に2つの問題があり、本当にアイデアを殺します:1ソルトをサーバーに戻す必要があります...クライアント側で暗号化するには、パスワードが必要です...これは目的に反します。 2.ハッシュの実装を公開し(ほとんどのサイトが3つまたは4つのハッシュアルゴのいずれかを使用するため、大したことではありません)、攻撃を容易にします(nではなく1つを試す必要があるため)。

最終的に私が行ったのは、OpenPGP.jsなどを使用したクライアント上の非対称暗号化でした...これは、クライアント上のインポートまたはクライアント側で生成されたキーと、公開キーを送信するサーバーに依存します。クライアントの公開鍵のみがサーバーに送り返されます。これにより、MIM攻撃から保護され、デバイスと同じくらい安全です(現在、デフォルトではクライアントの秘密キーをlocalStoreに保存していますが、これはデモです)。

これの主な利点は、ユーザーデータをサーバー/データストアで暗号化されていないメモリに保存する必要がないことです(サーバーの秘密キーは物理的に分離されています)

これの基礎は、HTTPSが制限されている場所(イラン/北朝鮮など)で安全に通信する方法と、楽しい実験を人々に提供することでした。

私は最初からこれを考えるのが遠いです http://www.mailvelope.com/ はこれを使用します

1
ScottGal

誰かがあなたの接続でデータの出入りを見ることができる場合、認証はあなたを救いません。代わりに、極秘のものに対して次のことを行います。

サーバーに送信される前にクライアント側で事前にハッシュされたパスワード。 (サーバーは、ブラウザから送信されたハッシュの別のハッシュ値とソルト値を保存します)。

そのため、中間者攻撃では、同じハッシュ値を送信してログインすることができますが、ユーザーのパスワードはわかりません。これにより、同じ資格情報を持つ他のサービスが他の場所にログインしようとするのを防ぐことができます。

ユーザーデータもブラウザ側で暗号化されます。

ああ、中間者攻撃は暗号化されたデータを取得しますが、ログインに使用される実際のパスワードなしではデータを復号化できません。 (ログイン時にブラウザのDOMに保存されたユーザーパスワード)。したがって、実際のユーザーには復号化されたコンテンツが表示されますが、中間のユーザーには表示されません。これは、NSAまたは他の機関もこのデータを解読することは不可能であるため、あなた/会社/ホスティングプロバイダーにこのデータの解読を要求できないことを意味します。

これらの両方の方法の小さな例が私のブログにあります http://glynrob.com/javascript/client-side-hashing-and-encryption/

1
GlynRob

このことを考慮:-

クライアントがサーバーにリクエストを送信します「検証するパスワードがあります」。

サーバーは、クライアントに1回限りのランダム文字列を送信します。 R $

クライアントは、このストリングにユーザーのパスワードを埋め込みます(適用する(可変)ルールに基づいて)。

クライアントは文字列をサーバーに送信し、パスワードが正常であれば、サーバーはユーザーをログインさせます。

サーバーがR $を使用して別のログインリクエストを受信した場合、ユーザーはログアウトされ、調査のためアカウントは凍結されます。

明らかに、他のすべての(通常の)セキュリティ予防措置が講じられます。

0
cneeds