サーバー側に送信する前にパスワードをハッシュする必要がありますか?


110

ほとんどのサイトがパスワードをプレーンテキストとしてHTTPS経由でサーバーに送信していることに気付きました。その代わりにパスワードのハッシュをサーバーに送信した場合、何か利点はありますか?より安全でしょうか?


5
@Jader Dias:これは聞かなかったと思いますが、ハッシュしても安全ではないので、httpsで送信します。実際、ソルトを公開しているため、安全性が低下する可能性があります。また、(ここで私の裏側を説明します)、アルゴリズムを混在させると、ハッシュの衝突が多くなり、ハッキング可能になる可能性があります。
Merlyn Morgan-Graham

@マーリン「ハッシュ衝突」の良い点!
Jader Dias、2010

混合アルゴリズムは、衝突確率をまったく増加させません。これがハッシュ関数の要点です。入力エントロピーが与えられると、可能な出力空間のどこかにある確率が等しい出力を返します。
JJ

@JJ「混合アルゴリズムは衝突確率をまったく増加させません。」私はその声明の証拠を本当に見たいと思っています。やめさせてください。これはfalseです。一般に、衝突が増加します。h(x)が定数0ではなく、すべてのxに対してh(h(x))= 0になるようなハッシュ関数を簡単に作成できます。したがって、ハッシュアルゴリズムの正確なセットと、それらをどのように組み合わせるかを参照する必要があります。次に、ステートメントを証明する必要があります。AFAIKは複数のSHA(saltを含む)の場合でも未解決の問題です。そして、基本的に私たちはこれが真実であると信じています。暗号化は難しいです。
気まぐれ

回答:


155

これは古い質問ですが、この重要な問題について私の意見を述べる必要があると感じました。ここには多くの誤報があります

OPは、HTTPを介してパスワードを平文で送信することについて決して言及していません-HTTPSのみですが、多くの人が何らかの理由でHTTPを介してパスワードを送信するという質問に答えているようです。それは言った:

パスワードをプレーンテキストで保持する(送信するだけでなく)ことは絶対に避けてください。つまり、ディスク、またはメモリに保存されていません。

ここで回答する人々は、HTTPSは特効薬だと思っているようですが、そうではありません。ただし、これは確かに非常に役立ち、認証されたセッションで使用する必要があります。

元のパスワードが何であるかを知る必要は本当にありません。 必要なのは、ユーザーが選択した元のテキストに基づいて認証「キー」を生成する(そして確実に再生成する)信頼できる方法です。理想的な世界では、このテキストは不可逆的なソルトを使用してハッシュすることにより、「キー」を即座に生成する必要があります。このソルトは、生成されるユーザー資格情報に固有である必要があります。この「キー」は、システムがパスワードとして使用するものです。このようにして、将来システムが危険にさらされた場合、これらの資格情報は自分の組織に対してのみ有効であり、ユーザーが怠惰で同じパスワードを使用した他の場所では役に立ちません。

だから私たちは鍵を持っています。次に、クライアントデバイス上のパスワードの痕跡をクリーンアップする必要があります。

次に、そのキーをシステムに取得する必要があります。鍵やパスワードを「平文で」送信してはいけません。HTTPSを介してさえ。HTTPSは貫通できません。実際、多くの組織は、攻撃の観点からではなく、トラフィックを検査して独自のセキュリティポリシーを実装することで、信頼できるMITMになることができます。これはHTTPSを弱体化し、それが発生する唯一の方法ではありません(たとえば、HTTP MITM攻撃へのリダイレクトなど)。安全だと思い込まないでください。

これを回避するために、1回限りのナンスでキーをハッシュします。このナンスは、システムにキーを送信するたびに一意になります。複数回送信する必要がある場合は、同じセッション中の同じ資格情報についても同じです。自分のシステムに到着したら、このナンスを逆にして、認証キーを回復し、リクエストを認証できます。

この時点で、自分のシステムに永続的に保存される前に、不可逆的にハッシュします。こうすることで、SSOなどの目的でクレデンシャルのソルトをパートナー組織と共有でき、自分の組織がユーザーになりすますことができないことを証明できます。このアプローチの最も優れた点は、ユーザーの許可なしにユーザーが生成したものを共有することがないことです。

私が明かしたよりも多くのことがあるので、より多くの調査を行いますが、ユーザーに真のセキュリティを提供したい場合は、この方法が現在ここで最も完全な応答だと思います。

TL; DR:

HTTPSを使用します。パスワードごとに固有のソルトを使用して、不可逆的にパスワードを安全にハッシュします。クライアントでこれを行います-実際のパスワードを送信しないでください。ユーザーの元のパスワードをサーバーに送信することは決して「OK」または「Fine」ではありません。元のパスワードの痕跡をクリーンアップします。HTTP / HTTPSに関係なくnonceを使用します。多くのレベルではるかに安全です。(OPへの回答)。


25
GmailとFacebookを確認しました-Chrome開発者ツールは、ユーザー名とパスワードをプレーン(無塩)テキストで含むURLエンコードされたメッセージでPOSTの両方を通知します。ビッグプレーヤーがクライアントでnonceソルトを使用しないのはなぜですか。
gremwell

18
ナンスを使用してキーをハッシュし、サーバー側でナンスをリバースできると主張します。ハッシュをブルートフォースしますか?または、hash = HASH(secret + nonce)を取得したときにnonceをどのように取得しますか?HASHは不可逆的な関数でなければなりません。これを実装しましたか?あなたが説明することは現実的ではないと思います。プロトコルのフローチャートを作成できますか?
シルバー

19
HTTPSを信頼しない場合、すべての努力は無意味です!コード自体はネットワーク経由で送信され、攻撃者は転送中のパスワードを保護するためのすべての試みを変更/置換できます
Sajid Kalla

3
証明書を書き換えることができるMitMは、ナンスを書き換えることができます。またはサジドが言ったこと。
leewz

4
HTTPSを使用したMITMが心配な場合は、クライアントにソルトを送信して、クライアントがハッシュをサーバーに送信する前にパスワードをソルトできるようにする意味は何ですか?意味がないようです。また、無塩ハッシュをサーバーに行い、ソルトを使用してサーバーで再度ハッシュすることもできます。明らかに、クライアントはクライアントソルトのジェネレーターになることはできません。次のログインは異なるため、同じハッシュサーバーサイドを計算しないためです。
クラッシュ

24

HTTPSを介しているため、ハッシュなしでパスワードを送信しても問題ありません(HTTPSを介してプレーンテキストではありません)。さらに、コンテンツを安全に保つためにアプリケーションがHTTPSに依存している場合、HTTPS経由で送信する前にパスワードをハッシュしても意味がありません(つまり、攻撃者がネットワーク上のデータの暗号化を解除できる場合は、とにかくねじ込まれます)。


5
これは問題になりません。クライアントがプロキシを使用している場合、プロキシに表示されるのはHTTPS暗号化データだけです。中間者攻撃について話している場合、適切に構成された証明書でこれを防ぐことができます。
Kiersten Arnold、2010

7
@Jader:データを何でも中継することができるため、データをいじってもMITM攻撃を阻止することはできません。パスワードとハッシュのどちらを送信するかは関係ありません。それはまったく別の問題です。
David Thornley、2010

2
SSL(HTTPS = HTTP over SSL)の目的はMITMを阻止することです。
yfeldblum 2010

1
@carnold-MINTM-httpへのリダイレクトについてはどうですか?ほとんどの人が気づくでしょうか?sslstrip - securityfocus.com/brief/910
ネイトC

1
@Jader Dias存在しない問題を阻止しようとしています。HTTPSはこの問題を阻止し、クライアント側のハッシュはセキュリティをまったく追加しません。クライアントを信頼することはできません。
2010

17

いいえ、実際、これは脆弱性になります。攻撃者がデータベースからハッシュを取得できる場合、攻撃者はそれをクラックする必要なしに認証に使用できます。いかなる状況でも、ユーザーまたは攻撃者はハッシュパスワードを取得できません。

パスワードをハッシュすることの要点は、セキュリティをさらに強化することです。攻撃者がSQLインジェクションまたは安全でないバックアップを使用してデータベースからハッシュとソルトを取得できる場合、攻撃者はブルートフォースでプレーンテキストを見つける必要があります。 John The Ripperは一般的に、ソルトされたパスワードハッシュを解読するために使用されます。

httpsを使用しないと、OWASP Top 10:A9-Insufficient Transport Layer Protectionに違反します

編集: 実装でを計算してsha256(client_salt+plain_text_password)から、サーバー側で別のハッシュを計算する場合、sha256(server_salt+client_hash)これは深刻な脆弱性ではありません。ただし、それでもリクエストを盗聴および再生する可能性があります。したがって、これはWASP A9の明らかな違反です。ただし、これはまだセキュリティレイヤーとしてメッセージダイジェストを利用しています。

私が見たクライアントサイドのhttpsの置き換えに最も近いのは、javascriptのキー交換におけるdiffie-hellmanです。ただし、これはアクティブなMITM攻撃を防ぐため、技術的にはOWASP A9の違反になります。コードの作成者は、これがHTTPSの完全な代替ではないことに同意しますが、何もないよりは優れており、クライアント側のハッシュシステムよりも優れています。


4
実際にはサーバーで再度ハッシュ化するので、このシナリオを考慮して回答を編集してください。
Jader Dias、2010

@Rookはhttpsと一緒にdiffie-hellman鍵交換を使用していますが、これは「役に立たない」ソリューションです。(つまり、httpsのみを使用でき、diffie helmanはセキュリティを向上させません)
Michel

@Michel Kogan DH鍵交換は、他のツールとともにHTTPで使用できます。
ルーク

1
@Rookサーバーにハッシュを適用することはベストプラクティスです。そのため、クライアント側のハッシュを無視しないように回答の最初を更新し、サーバーの格納されたハッシュとソルトは決して公開しないようにしてください。
LeventePánczél14年

8

攻撃者はハッシュを送信してパスワードを忘れることができるため、ネットワーク経由でハッシュを送信すると、ハッシュの目的が完全に無効になります。簡単に言えば、クリアテキストでハッシュを使用して認証するシステムはオープンであり、ネットワークスニッフィングだけで妥協することができます。


2
これは全体的に強そうです...ハッシュはパスワードより安全性が低いのはなぜですか?
LeventePánczél14年

1
これは、「ダム」ハッシュにのみ当てはまります。次の点を考慮してください。サーバーがソルトSをクライアントに送信し、クライアントがHASH(S + PASSWORD)を実行してサーバーに送信します。サーバーは、現在のセッションでのみその特定のハッシュを受け入れます。攻撃者は実際にハッシュを送信してパスワードを忘れることができますが、現在のセッションに対してのみです。したがって、プレーンテキストよりも安全です。
Hello World

更新:ダイジェストアクセス認証はさらに洗練されています:en.wikipedia.org/wiki/Digest_access_authentication
Hello World

2
はっきりさせておきますが、「ハッシュの目的に反する」と言ったときは、データベースに保存する前にパスワードをハッシュする一般的で安全な方法を指しています。それでもなお、パスワードの代わりにハッシュ値を送信することは、追加の手順なしにセキュリティを強化するためには何もしないと主張しています。
Paul Keister 2014年

Paulの発言に補足すると、この種類の攻撃は、他の場所で詳細を読みたい場合、「リプレイ攻撃」と呼ばれます。

5

プレーンテキストのパスワードは、(HTTPSを使用している場合でも)クライアントを離れることはありません。サーバーが実際のパスワードを知る必要がないため、クライアントを離れる前に不可逆的にハッシュする必要があります。

ハッシュしてから送信することで、複数の場所で同じパスワードを使用する怠惰なユーザーのセキュリティ問題が解決されます(私は知っています)。ただし、ハッカーはハッシュを送信してサーバーにそれを受け入れさせるだけなので、データベースにアクセスしたハッカー(または他の方法でハッシュを入手したハッカー)としてアプリケーションを保護することはできません。

もちろん、この問題を解決するには、サーバーが受信したハッシュをハッシュして、1日と呼ぶこともできます。

私が作成しているソケットベースのWebアプリケーションの問題への私のアプローチは、クライアントへの接続時にサーバーがソルト(ハッシュの前に追加されるランダムな文字列)を生成し、それをソケット変数に格納してから、このハッシュを送信することですクライアントに。クライアントはユーザーのパスワードを取得してハッシュし、サーバーからソルトを追加してすべてをハッシュしてから、サーバーに送信します。次に、このハッシュをハッシュと比較するサーバーに送信されます(DB内のハッシュ+ salt)。私の知る限り、これは良いアプローチですが、公平を期すために、このトピックについては多く読んだことがなく、何か間違っている場合は修正したいと思います。


3

HTTPダイジェストを使用-http経由でもパスワードを保護します(ただし、https経由のhttpダイジェストが最適です)

ウィキペディア:

HTTPダイジェストアクセス認証は、Webサーバーが(HTTPプロトコルを使用して)Webユーザーと資格情報をネゴシエートするために使用できる合意済みの方法の1つです。ダイジェスト認証は、基本アクセス認証の暗号化されていない使用に優先することを目的としているため、ネットワークを介してプレーンテキストでパスワードを送信する必要なく、ユーザーIDを安全に確立できます。ダイジェスト認証は基本的に、暗号解析を防ぐためにナンス値を使用するMD5暗号化ハッシュのアプリケーションです。

リンク:http : //en.wikipedia.org/wiki/Digest_access_authentication

「実際の」使用を確認したい場合は、phpMyID-httpダイジェスト認証http://siege.org/phpmyid.phpを使用するphp openidプロバイダーを見てください。

..または、http: //php.net/manual/en/features.http-auth.phpにあるphp authサンプルから開始できます。

HTTPダイジェストrfc:http : //www.faqs.org/rfcs/rfc2617

私のテストから、すべての最新のブラウザがそれをサポートしています...


HTTPダイジェストは、この質問で私が言ったことを実装していますが、HTTPSダイジェスト(SSL + HTTPダイジェスト)を使用した場合、何か利点がありますか?
Jader Dias、2010

主な違いの1つは、すべてが暗号化されて送受信されることです。httpヘッダーが送受信され、html応答が送信されます。中間者攻撃を使用してsslをランダムに「ハッキング」しようとする誰かにとって、httpダイジェストは、彼が別のより簡単なターゲットを検索できるようにする追加の動機になるでしょう。質問を誤解しているかもしれませんが、英語は私の第一言語ではありません。
vlad b。

パスワードのハッシュには大きな利点が1つあります。トラフィックが何らかの理由で記録またはキャプチャされると、その人にとって仕事が難しくなります。また、httpダイジェストを使用して、sslが必ずしも必要でない場合は、ユーザーにhttpとhttpsのどちらかを選択させることができます。または、別のサーバーに異なるプロトコルを使用することもできます(たとえば、httpsを適用せずにインポートおよびデータ(ユーザー名、アバターのアップロード)を表示/変更しませんが、請求およびサイトの他の部分にhttpsを適用します(そうすることで、一部のサーバー(必要な場合/必要な場合)
vlad b。2010

3

HTTPSを介したクリアテキストのパスワードを、HTTPを介したハッシュ化されたパスワードに置き換える場合は、問題が発生します。HTTPSは、通信チャネルを開くときにランダムな共有トランザクションキーを生成します。(比較的)短期間のトランザクションに使用される共有キーをブルートフォースに強制することにほとんど制限がないため、これを解読するのは困難です。一方、ハッシュは盗聴され、オフラインにされて、レインボーテーブルで調べられたり、長時間にわたって強引に強制されたりする可能性があります。

ただし、HTTPS経由で送信される(ハッシュではなく)基本的なクライアント側のパスワードの難読化には、ある程度の価値があります。誤解しない限り、この手法は実際には一部の銀行で使用されています。この手法の目的は、パスワードをネットワーク上で盗聴することから保護することではありません。むしろ、それは、彼らが見るすべてのHTTPS GET / POSTリクエストを取得するスパイツールやブラウザのプラグインを弱めるためにパスワードが使用できないようにすることです。ユーザーセッションからキャプチャされた400MBのランダムなGET / POSTトランザクションである悪意のあるWebサイトからキャプチャされたログファイルを見ました。HTTPSだけを使用したWebサイトはログにクリアテキストのパスワードが表示されますが、非常に基本的な難読化(ROT13)を使用するWebサイトも、すぐには使用されないパスワードが表示されると想像できます。


「しかし、非常に基本的な難読化(ROT13)を行うWebサイトも、すぐには使用されないパスワードが表示されます」-これは、元のステートメントと矛盾します。重要なのは、それらがすぐに使用できるわけではないことですが、それは実際には無駄です。パスワードとそのROT13は同等です。ただし、パスワードをSHA2した場合、そのパスワードはログに表示されないため(管理者は他のシステムに対するユーザーの可能なパスワードを知ることができません)、ほとんどすべてのプライバシー法に違反することはもうありません。
LeventePánczél2014年

2

httpsサーバーに接続している場合は、サーバーとブラウザー間のデータストリームを暗号化する必要があります。データは、送信前と受信後のプレーンテキストのみです。ウィキペディアの記事


プロキシはこのデータを傍受しませんか?
Jader Dias、2010

私はそれを理解しているように、プロキシは暗号化/復号化の責任を負いません。悪質なプロキシでない限り、データを渡すだけです。暗号化のタイプと強度は、サーバーとクライアントの両方がサポートできるものによって異なります。
jac

1
プロキシが不当なものであっても、サーバーの公開鍵を使用して暗号化されているため、データを復号化できません。プロキシがデータを復号化できる唯一の方法は、別のキーでサーバーの証明書を偽装することです
Kiersten Arnold

@ジェダー。もしそうなら、それはHTTPSをかなり下手にさせるでしょう。HTTPSを使用してサーバーを認証すると、特定のサーバーに接続していること、および一端から他端へのパスが暗号化されていることが保証されます(証明書が有効であることが前提です)。仮に、中間者攻撃はもちろんあなたをだますために行われる可能性がありますが、それは基本的なWebプロキシと同じではありません。
Peter Recore 2010

2

免責事項:私はセキュリティエキスパートではありません。他の人が私の立場を過度に慎重または改善可能であると批判し、そこから学ぶことを期待して投稿しています。とはいえ、クライアントを離れるときにハッシュを実行しても、データベースに配置する前にバックエンドでハッシュを実行する必要がないことを強調する必要はありません。

両方する

両方を行う理由:

  1. 乗車時のハッシュは、トランスポートの脆弱性をカバーするのに役立ちます。SSL接続が侵害された場合でも、未加工のパスワードを見ることができません。承認されたユーザーになりすますことができるかどうかは関係ありませんが、ユーザーのパスワードがメールと関連付けられて読み取られるのを防ぐことができます。ほとんどの人はベストプラクティスに従っておらず、多くのアカウントで同じパスワードを使用しているため、これは訪問者にとって深刻な脆弱性になる可能性があります。

  2. 誰かが何らかの理由でデータベースからパスワードを読み取ることができた場合(これは起こりますが、SQLインジェクションと考えてください)、私のAPIを介してユーザーになりすましている特権アクションを実行することはできません。これはハッシュの非対称性が原因です。DBに保存されているハッシュを知っていても、それを作成するために使用された元のキーを知らないため、認証ミドルウェアが認証に使用します。これは、ハッシュストレージを常にソルトする必要がある理由でもあります。

確かに、データベースから必要なものを自由に読み取ることができれば、他の多くの損害を与える可能性があります。

ここで強調したいのは、クライアントから離れる前にキーをハッシュすることにした場合、それだけでは十分ではないということです。バックエンドハッシュは非常に重要です。これが理由です。誰かがあなたのトラフィックを傍受している場合クライアントの場合、passwordフィールドの内容が表示されます。これがハッシュであろうとプレーンテキストであろうと、それは問題ではありません。彼らはそれを逐語的にコピーして、許可されたクライアントになりすますことができます。(@ user3299591で説明されている手順を実行しない限り、実行することをお勧めします)。一方、DB列をハッシュすることは必須であり、実装することはまったく難しくありません。



0

パスワードをハッシュし、暗号化されていないチャネルを介して送信することは、実際には安全性が低くなります。ハッシュアルゴリズムをクライアントに公開します。ハッカーはパスワードのハッシュを盗聴し、後でそれを使用してハッキングすることができます。

HTTPSを使用することにより、ハッカーが単一のソースからパスワードを取得するのを防ぎます。これは、HTTPSが2つのチャネルを使用し、両方とも暗号化されているためです。


1
実際、サーバーで再度ハッシュし、とにかくHTTPSを使用するので、このシナリオを考慮して回答を編集してください。
Jader Dias

@Jader、要点は、攻撃者が今必要とするのはパスワードではなく最初のハッシュだけであるということです。実際、クライアント側でパスワードから取得するハッシュは、パスワード自体と同じくらい便利です。だからあなたは本当にそれほど多くのセキュリティを得ていません。
Peter Recore 2010

誰かがトークンの一部を送信しないと考えたことはありますか?あなたがハッシュの方法を知っているなら、なぜあなたはそれを送るのですか?サーバーは、復号化するクライアントキーを知っているべきではありませんか?
jemiloii 2017

0

アドバンテージがあるかどうか、そしてそれがより安全であるかどうかは、実装に依存します。間違いなくいくつかの利点がありますが、実装が不十分であれば、プレーンテキストのパスワードを渡すよりも安全性の低いソリューションを確実に作成できます。

これは、ネットワークトラフィックにアクセスする攻撃とデータベースにアクセスする攻撃の2種類の攻撃の観点から見ることができます。

攻撃者がネットワークトラフィックのプレーンテキストバージョンを傍受できる場合、パスワードのハッシュを表示する方が、プレーンテキストでパスワードを表示するよりも安全です。攻撃者はそのハッシュを使用してサーバーにログインすることもできますが、他のシステムで役立つパスワードを特定するために、そのハッシュのブルートフォースクラック(場合によっては事前計算)が必要になります。人々はさまざまなシステムでさまざまなパスワードを使用する必要がありますが、多くの場合は使用しません。

攻撃者がおそらくバックアップのコピーを介してデータベースにアクセスした場合、その知識だけではログインできないようにする必要があります。たとえば、ログイン名をソルト化したハッシュをとして保存し、hash(login_name+password)直接比較するためにクライアントから同じハッシュを渡した場合、攻撃者はユーザーをランダムに選択し、データベースから読み取ったハッシュを送信して、次のようにログインできます。パスワードを知らなくても、そのユーザーは侵害の範囲を拡大します。その場合、攻撃者はデータベースのコピーを持っている場合でも、ログインするために平文を知っている必要があるため、平文でパスワードを送信する方がより安全です。 ここで、実装が重要です。 プレーンテキストのパスワードを送信する場合でも、そのパスワードのクライアント側のハッシュを送信する場合でも、その値をサーバー側でハッシュし、そのハッシュをユーザーレコードに格納されているハッシュと比較する必要があります。

覚えておくべき概念:

  • スコープ固有の値をハッシュ(通常は行固有)に混合することにより、ハッシュを「ソルト」します。その目的は、それらが表す平文の値が同じである場合でも、お互いのハッシュの一意性を保証することです。そのため、同じパスワードを持つ2人のユーザーが異なるハッシュを持つことになります。塩を秘密として扱う必要はありません。
  • 認証時には、常にクライアントからパスワードとして渡した値をサーバー側でハッシュし(既にハッシュされている場合でも)、データベースに格納されているハッシュ済みの値と比較します。これには、元のパスワードのダブルハッシュバージョンの保存が必要になる場合があります。
  • ハッシュを作成するときは、サーバー/クラスター固有のソルトと行固有のソルトをハッシュに追加して、ルックアップテーブル内の事前に計算されたハッシュと一致しないようにすることを検討してください。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.