web-dev-qa-db-ja.com

WebSocketを使用してユーザーを認証する最良の方法は何ですか?

私は、ブラウザから直接実行され、マルチプレイヤー機能を備えたマルチプレイヤーゲーム(WebSocketに基づく)を作成しています。各プレイヤーは自分のアカウント(ユーザー名とパスワード)を持っている必要があります。ゲームを計画していたときに、それを他のプラットフォームに移行する最も簡単な方法は、HTML5でそれを書くことだと気付きました。したがって、JSとWebSocketを使用してログインシステムを作成する必要があります。しかし、ユーザー名やパスワードなどのコンテンツを含むメッセージを、WebSocketサーバー(Java仮想マシンで実行される)に送信することで安全かどうかはわかりません。

6
zearthur99

セキュリティが必要な場合は、TLSを介した認証データの送信が大きな始まりです。しかし、WebSocketがすでにTLSを介して設定されていると仮定しましょう。私がお勧めするソリューションは、チャレンジ/レスポンスメカニズムに基づくものです。

  1. サーバーはランダムなバイトのセット(チャレンジ)を設定し、最後にチャレンジが承認されないタイムアウトを設定します。
  2. クライアントは、ユーザー名とチャレンジ、およびchallenge || username || f(password)のハッシュと(SHA2またはSHA3アルゴリズムを使用した)ハッシュを「プレーンテキスト」で送信します。f(password)は、データベースにパスワードを格納する方法です。 (たとえば、passwordのSHA256)。
  3. サーバーはユーザー名のデータと応答のチャレンジを検証し、そうであればユーザーを認証します。また、このチャレンジを使用した今後の試行を無効にするチャレンジも無効にします。

この方法は、リプレイ防止機能を提供します。攻撃者はデータをキャプチャし、後で再生して認証することができませんでした。

ただし、この方法には大きな問題が1つあります。f(password)のセキュリティはpasswordとほぼ同じです。データベースが漏洩した場合、攻撃者は他のユーザーと同じように認証される可能性があります。 「大まかに」と言います。なぜなら、多くのユーザーが複数のWebサイトで同じパスワードを使用しているため(これは悪いことです)、平文で保存されていると、アカウントが他の場所で侵害される可能性があるからです。

データベースリークとアンチリプレイメカニズムから保護する方法は考えられませんが、データベースリークメカニズム(ユーザーパスワードをクリアテキストでTLS経由で送信し、パスワードをデータベースソルトでハッシュし、データベースと比較します)はTLS経由で行う必要がありますあなたが直面するほとんどのリスクに対して十分である

8
Aniem

パスワードが必要な場合は、TLSを使用して、パスワードを平文で送信するのが最善の方法です。これは、チャレンジ/レスポンスメカニズムよりも簡単です。

ただし、WebSocketにTLSを使用できないが、コード(HTTP経由で配信)にTLSを使用している場合は、HTTPS経由でログインし、セッションCookie(またはその他の形式のキー)を生成して使用するのが最善の方法です。 WebSocketを認証します。平文でチャレンジ/レスポンスを行うと、攻撃者はその通信を使用してパスワードを総当たり攻撃することができます。セッションアプローチでは、攻撃者は(機密性の低い)ゲームのセッションのみをキャプチャでき、(おそらく再利用される)パスワードはキャプチャできません。ただし、どちらにもTLSがない場合は、サードパーティを介してユーザーを認証する必要があります。 OpenIDを通じて。そうすれば、パスワードなどの機密データを処理する必要がなくなります。 OpenIDは、他の場合にも適したオプションです。

2
user10008