web-dev-qa-db-ja.com

HTTP経由で安全にパスワードを送信する方法は?

ログイン画面でユーザーがユーザー名とパスワードを使用してフォームを送信すると、パスワードはプレーンテキストで送信されます(POSTを使用しても、間違っている場合は修正してください)。

質問は、通信データを盗聴する可能性のある第三者からユーザーとパスワードを保護する正しい方法は何ですか?

HTTPSが問題の解決策であることは承知していますが、標準のHTTPプロトコル(POSTリクエスト)を使用して少なくともある程度のセキュリティを確保する方法はありますか? (おそらく何らかの方法でjavascriptを使用しています)

EDITいくつか重要なことを省いたかもしれません。

私がやっていることはページでした-それはPHP生成されたログインページで、もちろんHTMLファイルとしてHTTP GETリクエストでユーザーに送信されます。サーバーとクライアントの間に(@Jeremy Powel)接続が確立されていないため、このようなハンドシェイクプロトコルを作成できません。そして、私は完全なプロセスがユーザーに透過的であることを望んでいます-ユーザーは暗号を扱うのではなくパスワードを提出したいのです。

ありがとう。

110
Kornelije Petak

HTTPでSSLを使用すると、人生がずっと楽になり、非常に賢い人(少なくとも私よりも賢い人)が安心して休むことができます。

61
Jeremy Powell

安全な認証は幅広いトピックです。簡単に言えば、@ jeremy-powellが述べたように、HTTPではなくHTTPSを介して資格情報を送信することを常に優先します。セキュリティ関連の多くの頭痛の種を取り除きます。

最近、TSL/SSL証明書はかなり安価です。実際、お金をまったく使いたくない場合は、無料のletsencrypt.org-自動認証局があります。

さらに一歩進んで、バックグラウンドでletsencryptを呼び出すcaddyserver.comを使用できます。

さて、HTTPSが邪魔にならないようにしたら...

POSTペイロードまたはGETパラメーターを使用してログインとパスワードを送信しないでください。代わりに、次のように構築されたAuthorizationヘッダー(基本アクセス認証スキーム)を使用します。

  • ユーザー名とパスワードは、コロンで区切られた文字列に結合されます。例:username:password
  • 結果の文字列は、Base64のRFC2045-MIMEバリアントを使用してエンコードされますが、76文字/行に限定されません。
  • 承認方法とスペース、つまり「Basic」がエンコードされた文字列の前に配置されます。

ソース: Wikipedia:Authorization header

少し複雑に見えるかもしれませんが、そうではありません。すぐにこの機能を提供する優れたライブラリがたくさんあります。

Authorizationヘッダーを使用する理由はいくつかあります

  1. それは標準です
  2. 簡単です(使用方法を学んだ後)
  3. 次のように、URLレベルでログインできます:https://user:[email protected]/login(たとえば、Chromeは自動的にAuthorizationヘッダーに変換します)

重要:
@ zaphの以下のコメントで指摘されているように、GETクエリとして機密情報を送信することは、サーバーログに記録される可能性が高いため、お勧めできません。

enter image description here

29
FullStackForger

チャレンジレスポンススキームを使用できます。クライアントとサーバーの両方がシークレットSを知っているとしましょう。サーバーは、クライアントがパスワードを知っていることを確認できます(パスワードを渡さずに)。

  1. サーバーはクライアントに乱数Rを送信します。
  2. クライアントはH(R、S)をサーバーに送り返します(HはSHA-256などの暗号化ハッシュ関数です)
  3. サーバーはH(R、S)を計算し、それをクライアントの応答と比較します。一致する場合、サーバーはクライアントがパスワードを知っていることを知っています。

編集:

ここには、Rの鮮度と、HTTPがステートレスであるという問題があります。これは、サーバーにシークレットを作成させ、Qと呼び、サーバーだけが知っていることで処理できます。次に、プロトコルは次のようになります。

  1. サーバーは乱数Rを生成します。次に、クライアントH(R、Q)に送信します(クライアントは偽造できません)。
  2. クライアントはR、H(R、Q)を送信し、H(R、S)を計算してサーバーに送り返します(HはSHA-256などの暗号化ハッシュ関数です)
  3. サーバーはH(R、S)を計算し、それをクライアントの応答と比較します。次に、Rを取り、(再び)H(R、Q)を計算します。クライアントのバージョンのH(R、Q)およびH(R、S)がサーバーの再計算と一致する場合、サーバーはクライアントが認証されたとみなします。

H(R、Q)はクライアントによって偽造できないため、H(R、Q)はCookieとして機能します(したがって、実際にはCookieとして実装できます)。

別の編集:

H(R、Q)を観察した人は誰でも正しいハッシュでリプレイできるようであるため、プロトコルに対する以前の編集は正しくありません。サーバーは、どのRが最新ではなくなったかを覚えておく必要があります。私はこの答えをCWしているので、皆さんはこれを編集して、何か良いことをすることができます。

14
Jeremy Powell

Webホストで許可されている場合、または機密データを処理する必要がある場合は、HTTPS期間を使用します。 (多くの場合、法律afaikで要求されています)。

それ以外の場合は、HTTP経由で何かをしたい場合。私はこのようなことをします。

  1. サーバーは、その公開鍵をログインページに埋め込みます。
  2. クライアントはログインフォームに入力し、[送信]をクリックします。
  3. AJAXリクエストは、サーバーから現在のタイムスタンプを取得します。
  4. クライアント側のスクリプトは、資格情報、タイムスタンプ、およびソルト(マウスの動き、キー押下イベントなどのアナログデータからハッシュ化)を連結し、公開キーを使用して暗号化します。
  5. 結果のハッシュを送信します。
  6. サーバーはハッシュを解読します
  7. タイムスタンプが十分に新しいかどうかを確認します(5〜10秒の短いウィンドウのみを許可します)。タイムスタンプが古すぎる場合、ログインを拒否します。
  8. ハッシュを20秒間保存します。この間隔中のログインに対して同じハッシュを拒否します。
  9. ユーザーを認証します。

そのため、この方法ではパスワードが保護され、同じ認証ハッシュを再生できません。

セッショントークンのセキュリティについて。それは少し難しいです。ただし、盗まれたセッショントークンの再利用を少し難しくすることは可能です。

  1. サーバーは、ランダムな文字列を含む追加のセッションCookieを設定します。
  2. ブラウザは次のリクエストでこのCookieを送り返します。
  3. サーバーはCookieの値を確認し、異なる場合はセッションを破棄します。それ以外の場合はすべて問題ありません。
  4. サーバーは、異なるテキストを使用してCookieを再設定します。

したがって、セッショントークンが盗まれ、リクエストが他の誰かによって送信された場合、元のユーザーの次のリクエストでセッションが破棄されます。そのため、ユーザーがリンクを頻繁にクリックしてサイトを積極的に閲覧している場合、盗人は盗まれたトークンを手放すことはできません。このスキームは、重要な操作(アカウントの削除など)に別の認証を要求することで強化できます。

編集:攻撃者が別の公開鍵を使用して独自のページを設定し、サーバーへのプロキシリクエストを行った場合、これはMITM攻撃を防止しないことに注意してください。これを防ぐには、ブラウザのローカルストレージまたはアプリ内で公開キーを固定して、この種のトリックを検出する必要があります。

実装について:RSAはおそらく最もよく知られているアルゴリズムですが、長いキーの場合は非常に低速です。 PHPまたはJavascriptの実装がどれほど高速になるかわかりません。しかし、おそらくより高速なアルゴリズムがあります。

10
Calmarius

サーバー側とクライアント側のDiffie-Hellman鍵交換システムとAJAXまたは複数のフォーム送信(前者をお勧めします)を使用しますが、インターネット上での適切な実装は見当たりません。 JSライブラリは、MITMによって常に破損または変更される可能性があることに注意してください。ローカルストレージを使用して、ある程度これに対処することができます。

4
Andrey Akhmetov

SRP を使用して、安全でないチャネルで安全なパスワードを使用できます。利点は、攻撃者がトラフィックを盗聴したり、サーバーを侵害したりしても、別のサーバーでパスワードを使用できないことです。 https://github.com/alax/jsrp は、ブラウザまたはサーバー側(ノード経由)でHTTP経由の安全なパスワードをサポートするjavascriptライブラリです。

3
Brian Minton

HTTPSは非対称暗号を使用するため、非常に強力です。このタイプの暗号化では、暗号化されたトンネルを作成できるだけでなく、ハッカーではなく適切な人と話していることを確認できます。

非対称暗号RSA(PGPで使用)を使用して通信するJavaソースコードは次のとおりです。 http://www.hushmail.com/services/downloads/

1
rook

ホストにsslを使用できます。letsencrypt https://letsencrypt.org/ のようなssl用の無料プロジェクトがあります。

0
mk990