web-dev-qa-db-ja.com

httpsセキュリティ-パスワードはサーバー側またはクライアント側でハッシュする必要がありますか?

ユーザーにログインを要求するWebアプリケーションを構築しています。すべての通信はhttpsを経由します。パスワードのハッシュにbcryptを使用しています。

私はジレンマに直面しています-以前は(JavaScriptを使用して)パスワードハッシュを作成し、それをDBサーバー側のハッシュと比較する方が安全であると考えていました。しかし、これがプレーンテキストのパスワードをhttps経由で送信し、サーバー側でハッシュするよりも良いかどうかはわかりません。

私の考えは、攻撃者がhttpsトラフィックを傍受できる(=プレーンテキストのパスワードを読み取る)場合、たとえば、JavaScriptを変更して、ハッシュされたパスワードと一緒にプレーンテキストのパスワードを送信して、傍受できるということです。

againstハッシュクライアント側の理由は、使いやすさです。クライアント側をハッシュする場合、2つの別個のライブラリを使用してハッシュする必要があります。これは乗り越えられない問題ではありませんが、迷惑です。

クライアント側のハッシュを使用することで安全性の向上はありますか?どうして?

その場合、チャレンジ/レスポンスも使用する必要がありますか?

PDATE:私にとって最も興味深いのはこれです。これらの手法(クライアント側のハッシュ、要求/応答)は、httpsが使用されている場合にセキュリティ上の重要な利点を追加しますか?もしそうなら、なぜですか?

116
johndodo

クライアント側でハッシュすると、ハッシュされたパスワードが実際のパスワードになります(ハッシュアルゴリズムはser-heldニーモニックを実際のパスワードに変換する手段にすぎません)。

これは、完全な"plain-text"パスワード(ハッシュ)をデータベースに保存することを意味し、最初からハッシュの利点をすべて失っています。

この方法を選択する場合は、ハッシュを行わずに、ユーザーの未加工のパスワードを送信して保存することもできます(ちなみに、これは特にお勧めしません)。

124
Nicole Calinoiu

クライアントでのハッシュは、何らかの方法でサーバーを信頼せず、「実際の」パスワード(ユーザーが覚えているパスワード)を表示したくない場合にのみ意味があります。上記のパスワードが使用されているまさにそのサイトにパスワードを表示したくないのはなぜですか?他の場所でパスワードを再利用したためです!さて、それは通常悪いことですが、無数のブラウザ拡張機能や this this または その1つ (私はそれらの品質を保証しません)。これらは、2つの異なるサイトが異なるパスワードを取得できるように、サイトのドメイン名を一種のソルトとして使用して、サイト固有のパスワードが生成される「マスターパスワード」を人間のユーザーが覚えているツールです。

このシナリオは理にかなっていますが、サーバー自体によって送信されたJavascriptでそれを行うことはできません。実際、クライアント側でパスワードをハッシュ化するポイントは、サーバーが潜在的に敵対的である(たとえば、攻撃者によって破壊される)ことであり、そのため、そのサーバーによって送信されたJavascriptコードは、少なくとも疑わしいものです。悪意のあるJavascriptに貴重なパスワードを入力したくない...


クライアント側ハッシュのもう1つのケースは、約 slow hashing です。パスワードは本質的に脆弱であるため、 辞書攻撃 を阻止する必要があります。あなたは悪意のある人がサーバーデータベースのコピーを入手し、自分のマシンで「パスワードを試す」ことを想定しています(これについての議論は このブログ投稿 を参照)。敵対者を遅くするには、本質的に遅いハッシュプロセス( bcrypt など)を使用しますが、これによりサーバーを含むすべての人の処理が遅くなります。サーバーを支援するために、クライアントでの作業の一部をオフロードしたい場合があります。そのため、クライアントブラウザーで実行されているJavascriptコードで少なくともその一部を実行します...

残念ながら、Javascriptはこの種の仕事ではひどく遅く(通常、まともなCコードよりも20から100倍遅い)、クライアントシステムはハッシュ作業に実質的な部分を提供できません。アイデアは正しいですが、より良い技術を待つ必要があります(ただし、 Java クライアントで動作しますが、適切なJVMを使用すると、最適化されたJavaコードはハッシュジョブの場合、最適化されたCコードよりも約2〜4倍遅くなります)。


要約すると、サーバー自体によって送信されたJavascriptコードから、クライアント側のパスワードハッシュを実行するための本当に良いケースはありません。 HTTPSトンネルを介して「現状のまま」パスワードをサーバーに送信するだけです(ログインページ、フォームの宛先URL、およびパスワードで保護されているページはすべてallSSL経由で提供されます。それ以外の場合は、パスワードの使用よりも差し迫ったセキュリティ問題があります)。

32
Thomas Pornin

私はすべての懸念が適切であると思いますが、サーバー側で行うことをお勧めします。

ユーザーが端末のロックを解除したままにして、操作を許可する可能性はかなり高くなります。そしてまた;ハッシュロジックがクライアント側である場合は、それを公開しています。

別のオプションは、サーバー側でパスワードを生成することです。その後、クリアテキストのパスワードで送信していません。ただし、ユーザーにパスワードを伝える必要があります。また、ほとんどのユーザーは暗号化された電子メールをまだ使用していないため、安全性は低いと考えています。

暗号化されたトンネルを介してパスワードを携帯電話に送信するソリューションを見てきました。しかし、セキュリティがSSLよりも優れているとは思えません。おそらく誰かがこれを証明/反証できるでしょうか?

11
rmorero

他のすべての回答が示しているように、サーバー側のハッシュは重要ですが、クライアント側のハッシュは素晴らしいセキュリティ機能さらにをサーバー側のハッシュに追加したいと思います。

クライアント側のハッシュには、次のシナリオで利点があります。

  1. サーバーが危険にさらされたときにユーザーのパスワードを保護します。つまりクライアントが危険にさらされていないが、サーバーが危険にさらされている場合、クライアントがパスワードをハッシュしても、サーバーは1つのシステムにアクセスできますが、ユーザーのパスワードを保護しました。
  2. ユーザーがあるサーバーにログインしているとユーザーが考えているが、実際には別のサーバーにログインしている(ユーザーエラー)場合に、ユーザーのパスワードを保護します。たとえば、銀行口座が2つあり、誤って自分の銀行のパスワードの1つを間違った銀行のWebサイトに入力した場合、その銀行がクライアント側のハッシュ化されたパスワードで他の銀行のパスワードを知らないでしょう。クライアント側をハッシュしてプレーンテキストのパスワードがネットワーク経由で送信されないようにすることは、「丁寧な」ことだと思います。

ほとんどの場合、ユーザーのパスワードを尊重しています。ユーザーがソフトウェアに限定されない可能性のある秘密を共有しているため、その秘密を尊重する場合は、それを保護するためにすべてのことを行う必要があります。

10
Samuel

HTTPSトンネルを使用している場合は、パスワードまたはハッシュをイーサネット監視から保護する必要があります。

クライアント側では、ハッシュをセッションIDでソルトできます。
これは、悪意のあるJavascriptのシミュレーションが困難になる可能性があります。

2
bua

あなたは両方を行うことができます、それをクライアントでハッシュするので、攻撃者がhttpsセキュリティを通過できる場合、彼らはプレーンテキストのパスワードを見ることができなくなります。次に、サーバーで再度ハッシュするので、攻撃者がサーバーに格納されているパスワードを取得した場合、サーバーに送信してパスワードにアクセスすることはできません。

1
nat that

クライアント側でパスワードをハッシュするには、Javascriptが必要です。一部の人々は彼らのブラウザでJavaScriptを無効にします。このシナリオを処理する必要があります。

クライアント側でパスワードハッシュを実行し、ログイン時にハッシュを送信するフォーラムソフトウェアを見てきました可能な場合、それ以外の場合、パスワードはプレーンテキストで送信されます。したがって、どちらの状況でも機能します。

パスワードを平文で送信することは、httpsを使用する場合は大きな懸念事項ではありません。理想的には、サーバーがhttpでページを提供することを拒否して、中間者攻撃を回避する必要があります。その理由は、攻撃者がhttpsからhttpに接続を強制的に「ダウングレード」し、トラフィックを盗聴することです(たとえば、SSL Stripのようなツールを使用)。

1
Anonymous

@ Nicole Calinoiu の受け入れられた答えはもちろん正しいですが、最初は理解しにくいかもしれません。

重要なのは、悪意のある人物がサーバーのデータベースからハッキングしたハッシュを使用してアカウントまたはデータにアクセスできないようにするために、サーバーでパスワードをハッシュする必要があることです。

すでに述べたように、クライアント側でハッシュし、バックエンドがそれをサポートしている場合、ハッシュはパスワードになり、ハックによってハッシュが盗まれた場合、ハッカーはパスワードを持っています。

@ Thomas Pornin 答えは、クライアントでパスワードをハッシュしたいのですが、彼が説明していることも非常に良い点を考え出しました彼の最初の話では、サーバーのバックエンドがハッシュされたパスワードの処理をサポートしている場合(つまり、すでにハッシュされている場合はパスワードをハッシュしないが、誰かがそのようなものをサポートしようとする可能性は非常に低い)の場合にのみ実行できます。時間は私が推測するケースではありません。彼の第二話はとても良いです。

0
Ini