ログインシステムを導入するときは、常に、指定されたパスワードのMD5をサーバー側のユーザーテーブルの値と比較します。
しかし、私の友人は、「クリアな」パスワードがネットワークソフトウェアによって盗聴される可能性があると私に言った。
だから私の質問は:クライアント側でパスワードをハッシュするのは良い考えですか?サーバー側でハッシュするよりも良いですか?
ログインシステムを導入するときは、常に、指定されたパスワードのMD5をサーバー側のユーザーテーブルの値と比較します。
しかし、私の友人は、「クリアな」パスワードがネットワークソフトウェアによって盗聴される可能性があると私に言った。
だから私の質問は:クライアント側でパスワードをハッシュするのは良い考えですか?サーバー側でハッシュするよりも良いですか?
回答:
基本的に、あなたの友達は正しいです。ただし、クライアント側でパスワードをハッシュするだけの方が、プレーンテキストとしてサーバーに送信するよりも優れています。プレーンテキストのパスワードを聞くことができる人は、ハッシュされたパスワードを聞くこともでき、これらのキャプチャされたハッシュを使用してサーバーに対して認証します。
この問題に関して、より安全な認証プロトコルは通常、クライアントがランダムなビットの束を選択することを許可することにより、そのようなリプレイ攻撃が機能しないことを確認するために、多くのフープをジャンプします。 、またクリアテキストでサーバーに送信されます。
サーバー上:
クライアント上:
サーバーは自身のランダム情報とクライアントのランダムビット(それらをクリアテキストとして取得した)を知っているため、基本的に同じ変換を実行できます。このプロトコルは、両方の当事者が毎回異なる「ノイズビット」を生成する限り、この会話を聞いている誰もが後で情報を使用して、記録された情報を使用して誤って認証することができないことを確認します(非常に弱いアルゴリズムが使用された場合を除く)。握手が行われます。
編集これはすべてエラーが発生しやすく、面倒で、正しく理解するのがやや難しい(読み取り:安全)。可能であれば、知識のある人がすでに書いている認証プロトコルの実装を使用することを検討してください(私とは異なります。上記は、私が少し前に読んだ本のメモリからのみです。)通常、これを自分で書きたくはありません。
まず第一に、これはあなたのアプリケーションのセキュリティを向上させません(それがwebappであると仮定します)。
SSL(または実際にはTLS、通称SSLと呼ばれます)を使用します。これはそれほど高価ではありません(その方法を見つけて最低賃金で乗算するために使用している時間を測定し、証明書を購入するとほぼ常に勝ちます)。
これの理由は簡単です。TLSは、暗号で非常に大きな問題(自己署名ではなく購入した証明書で使用した場合)を解決します。私が話しているサーバーが、私が話していると思うサーバーであることをどのようにして知ることができますか?TLS証明書は言い方です。「ブラウザーによって信頼されている認証局である私は、[url]のWebサイトがこの公開鍵を持っていることを証明します。対応する秘密鍵は、サーバーだけが知っています(秘密鍵)ドキュメント全体に署名しました。誰かが変更した場合、あなたは見ることができます。」
TLSがなければ、暗号化は無意味になります。私がコーヒーショップであなたの隣に座っていると、私はあなたのラップトップ/スマートフォンに私がサーバーであり、MiTM(Man in The Middle)だと思わせることができるからです。TLSを使用すると、あなたのサイトに一致する認証局の署名付き証明書がないので、ラップトップ/スマートフォンは「信頼できない接続」と叫ぶでしょう。(暗号化と認証)。
免責事項:ユーザーはこれらの警告を右クリックする傾向があります:「信頼できない接続?何ですか?子猫の写真が欲しいだけです!例外を追加 してくださいクリックして 確認 してください YAYをクリックしてください!子猫!」
ただし、本当に証明書を購入したくない場合でも、クライアント側のJavaScriptハッシュを実装してください(そのためにスタンドフォードライブラリ(SJCL)を使用し、CRYPTO YOURSELFを絶対に実装しないでください)。
どうして?パスワードの再利用!HTTPSなしで簡単にセッションCookieを盗むことができます(これにより、私があなたのサーバーであるかのように見せかけることができます)(firesheepを参照)。ただし、送信前にパスワードをハッシュするJavaScriptをログインページに追加した場合(SHA256を使用するか、SHA256を使用し、SHA256を使用し、生成した公開鍵を送信し、それを使用してパスワードをハッシュ化して暗号化すると、saltを使用できませんこれで)、次に、ハッシュ/暗号化されたパスワードをサーバーに送信します。サーバー上のハッシュをソルトでハッシュし直し、それをデータベースに保存されているものと比較します(パスワードを次のように保存します:
(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を変更しない限り、しかし、ハッカーはおそらくHOWTO知ることができません/興味があるスターバックスこのため、)彼らはあなたのウェブアプリにアクセスできますが、彼らのメール/フェイスブック/その他にはアクセスできません (ユーザーが同じパスワードを使用する可能性があります)。(メールアドレスは、ログイン名であるか、Webアプリケーションのプロファイル/設定にあります)。
このことを心配しなくても大丈夫でしょう。Dirkが言及しているように、悪意のあるユーザーがネットワーク上にいる可能性があるパスワードをハッシュし、ハッシュが送信されるのを見て、同じハッシュを自分で送信することもできます。
それは少しそれはパスワードが何であるかを知っているから、悪意のあるユーザーを防ぐことで、より良い、しかし、彼らはまだログイン(または潜在的にすることができますので、元のパスワードを再構築する)、その有用ではないということ。
一般に、ユーザーのパスワードとデータの安全性が心配な場合(そして安全である必要があります!)、安全なSSLサーバーを使用することをお勧めします。なんらかの理由でこれが問題にならない場合は、ハッシュを使用する必要はありません。それはあいまいさによる単なるセキュリティです。
2014年8月を編集:通信自体を保護することがネットワークスニッフィング攻撃を防ぐ唯一の方法であるため、GoogleはWebサイトがどこでもHTTPSに切り替わることをますます強く求めています。送信されたデータを難読化しようとすると、専用の攻撃者が妨害されるだけで停止することはなく、開発者に危険な誤った安心感を与える可能性があります。
x
。集合的な効果を考えると、「はるかに良い」と言えます。複数のサービス間でソルトハッシュをブルートフォースするために使用されるパスワードの大規模なルックアップデータベースの構築を防ぐためです。IMO。参考として、AWS Cognitoがクライアントで実行する内容を確認してください。
この場合、クライアント側のハッシュの方が安全であることに私は反対です。安全性は低いと思います。
実際のパスワード(または暗号化されたパスワード)とは対照的に、データベースにパスワードのハッシュを格納することの全体的なポイントは、ハッシュから元のパスワードを取得することは数学的に不可能であることです(理論的には衝突を取得することは可能です)ハッシュ入力。難易度はハッシュアルゴリズムのセキュリティ強度に依存します)。ここで考えられる攻撃の方法は、潜在的な攻撃者が何らかの方法でパスワードストレージデータベースを侵害した場合でも、ユーザーの元のパスワードを取得できないことです。
認証メカニズムがパスワードのハッシュを送信する場合、このセキュリティ違反のシナリオでは、攻撃者は実際のパスワードを知る必要はありません。攻撃者は自分が持っているハッシュを送信するだけで、特定のユーザーのアカウントにアクセスできます。ひいてはシステム全体。これは、ハッシュされたパスワードを最初から保存するという点を完全に無効にします!
これを行うための本当に安全な方法は、クライアントにパスワードを暗号化するための1回限りの公開鍵を送信し、それを復号化してサーバー側で再度ハッシュすることです。
ちなみに、この種の質問は、おそらくSecurity StackExchangeに関するより専門的な回答を得るでしょう。
パスワードを第三者に対して安全に保つことだけがすべてではないことに注意してください。
すぐに、プライバシーとして関与している(そして今までそれがないときは、これらの日は?)あなたは、パスワードを知っている必要はありません。あなたが持っていないものを悪用したり漏らしたりすることはできません。そのため、クリアテキストのパスワードを決して見なければ、あなたもクライアントもよりよく眠ることができます。
したがって、ハッシュ/暗号化クライアント側は理にかなっています。
x
ユーザーへの鍵が手に入りn
ます。各サービスがクライアントを離れる前にパスワードを一意にハッシュする場合、クロスサービスパスワードの大規模なデータベースははるかに小さくなります。AWSのログイントラフィックを確認し、何を行うかを確認します。それは私の愛するワトソンの確率です。
場合によっては、クライアント側のハッシュを使用できますが、サーバー側のソルトは使用できません。
クライアント側のパスワード暗号化のリンクを見てください
私は最近これについて多くの作業を行ってきましたが、IRLはクライアント側のハッシュ/ 対称暗号化に2つの問題があり、本当にアイデアを殺します:1.サーバーに塩を戻す必要がありますSOMEHOW ...そして暗号化するにはクライアント側ではパスワードが必要です...これは目的に反します。2.ハッシュ実装を公開します(ほとんどのサイトは3つまたは4つのハッシュアルゴのいずれかを使用するため、大規模な取引ではありません)。これにより、攻撃が容易になります(nではなく1つだけ試す必要があるため)。
私が最終的に行ったのは、OpenPGP.jsなどを使用したクライアントでの非対称暗号化でした...これは、クライアントでインポートまたはクライアント側で生成された鍵と、サーバーがその公開鍵を送信することに依存しています。クライアントの公開鍵のみがサーバーに送り返される場合があります。これはMIM攻撃から保護し、デバイスと同じくらい安全です(私は現在、クライアントの秘密キーをデフォルトでlocalStoreに保存しています。これはデモです)。
これの主な利点は、ユーザーデータをサーバーやデータストアの暗号化されていないメモリに保存する必要がないことです(サーバーの秘密キーは物理的に独立しています)。
これの基本は、HTTPSが制限されている場所(Iran / N. Korea atc ...など)で安全に通信する方法を人々に提供することと、単なる楽しい実験を提供することでした。
これを最初に考えたのはFARです。http://www.mailvelope.com/はこれを使用します
誰かがあなたの接続でデータを見ることができれば、認証はあなたを救うことはありません。代わりに、私は超秘密のもののために次のことをします。
パスワードは、サーバーに送信される前にクライアント側でハッシュ化されています。(サーバーは、ブラウザーから送信されたハッシュの別のハッシュ値とソルト値を保存します)。
そのため、中間者攻撃では、同じハッシュ値を送信してログインすることを許可する可能性がありますが、ユーザーのパスワードは不明です。これにより、他の場所にログインするために同じ資格情報を使用して他のサービスを試行するのを阻止します。
ユーザーのデータもブラウザー側で暗号化されます。
ああ、そのため、中間者攻撃は暗号化されたデータを取得しますが、ログインに使用された実際のパスワードなしではデータを復号化できません。(ログイン時にブラウザのDOMに保存されているユーザーパスワード)。したがって、実際のユーザーは復号化されたコンテンツを見ることができますが、仲介者は見ることができませんでした。これはまた、NSAまたは他の機関があなた/会社/ホスティングプロバイダーにこのデータの復号化を要求できないことも意味します。
これらの両方の方法のいくつかの小さな例が私のブログにあり ますhttp://glynrob.com/javascript/client-side-hashing-and-encryption/
最近、GitHubとTwitterの両方が、パスワードが内部ログに保存されることを発表しました。バグ報告や、splunkに侵入したその他のログで不注意にこれが発生したことがあります。Twitterの場合、トランプのパスワードがそこにあった場合、管理者が「確認」するのは大変であり、他のサイトではおそらく管理者はそれをあまり使用しないため、大きな問題になります。管理者とは関係なく、パスワードを見ることは好きではありません。
したがって、問題は、セキュリティのためにクライアント側でハッシュを実行する必要があるかどうかですが、最終的にハッシュされてサーバー側で比較される前にパスワードを保護して、なんらかの方法でログに記録されないようにする方法です。
暗号化は悪い考えではありません。少なくとも開発者はいくつかのフープを飛ばさなければならないので、パスワードがログに記録された場合、暗号化キーを変更するだけで元のキーを破壊でき、そのデータは役に立たなくなります。しかも、キーを毎晩ローテーションすると、ウィンドウが大幅に縮小される可能性があります。
ユーザーレコードのハッシュをハッシュすることもできます。漏洩したパスワードは、ハッシュされたプレーンテキストのパスワードになります。サーバーは、ハッシュされたバージョンのハッシュを格納します。確かにハッシュはパスワードになりますが、写真の記憶がなければ、60文字の文字列を思い出すことはできません。ユーザー名でソルトします。ログインプロセス中にユーザーについて何かを収集できた場合(ユーザーレコードが存在することを公開していない場合)、それを加味して、サイト間で共有できないより堅牢なハッシュを作成できます。真ん中の人は、サイト間でキャプチャされたハッシュをカットアンドペーストすることはできません。
サーバーに送信されないCookieと組み合わせると、何かにアクセスする可能性があります。最初のリクエストで、キーを使用してCookieをクライアントに送信します。次に、Cookieがログインサービスに戻らないようにして、ログに記録される可能性がほとんどないようにします。キーをセッションストアに保存し、ログインが発生した直後またはセッションが期限切れになったときに削除します。これには、JWT担当者の状態が必要ですが、おそらくnosqlサービスを使用するだけです。
そのため、管理者は、splunkまたはバグ報告ツールでこれらのハッシュ化および暗号化されたパスワードのいずれかに遭遇します。彼らが暗号化キーを見つけることができなくなったとしても、彼らは役に立たないはずです。たとえ彼らが見つけたとしても、彼らはブルートフォースハッシュをしなければなりません。さらに、エンドユーザーは平文を何も送信しなかったため、途中の人は少なくとも苦労し、別のサイトにアクセスしてログインすることはできません。