web-dev-qa-db-ja.com

Webおよび安全でないHTTP-RSAを使用してクライアント側でパスワードを暗号化する

私の登録およびログインプロジェクト でクライアント側のパスワードハッシュを使用しました。

その目的は、HTTP要求の送信中に、受動的な攻撃者/盗聴者がユーザーのプレーンテキストのパスワードを発見するのを防ぐことです。

しかし、攻撃者はハッシュに対してブルートフォース攻撃を実行できます。そして、私はほとんどまたは少なくとも多くのパスワードがこの方法で発見されると思います、なぜならそれらは強力なブルートフォース攻撃に対して抵抗するには弱すぎるからです。

そこで、最近、非対称暗号化を使用することを考えました。

パスワードは、クライアント側の公開鍵で暗号化されます(ブルートフォース攻撃を不可能にするために、 ランダム化されたパディングを使用 )。

これは良い考えですか?

コストに見合う価値があるか?

そのようなスキームに関する問題を知っていますか?

関連情報があれば大歓迎です。

5
H M

まず、私はあなたが中間者攻撃を弱めるためにこれをしていると仮定しています(安全でないHTTPを介したプレーンテキストのパスワードに関してはこれが本当に唯一の問題です)

クライアント側のハッシュにはほとんどメリットがありません。攻撃者は、ハッシュを取得するときに、ハッシュをブルートフォースする必要はありません。 serverに必要なのはハッシュだけなので、攻撃者は単にハッシュを含むPOSTリクエストを作成し、それを送信することができます。システムに入るのに平文は必要ありません。

あなたの解決策について:

すべてのクライアントに同じ公開鍵を使用している場合、状況は事実上同じです。攻撃者としてあなたが傍受する必要があるのはあなたが送信する暗号文だけであり、私は同じ暗号文を送信することであなたになりすますことができます。

各ログインで各クライアントに異なる公開鍵を与えた場合はどうなりますか?次に、中間攻撃を仕掛け、サーバーの公開鍵を自分の鍵と交換し、送信した暗号文を復号化して(これにより平文が得られます)、サーバーの公開鍵で暗号化します。

gotがあり、クライアントがどの公開鍵が正しいかを知ることができます。そのためには、何らかの信頼システムが必要になります。クライアントは、どの公開鍵がどのサーバーに対応するかを知っています。しかし、これは何百万もの公開鍵がブラウザに保存されることにつながります。したがって、何らかの証明書チェーンシステムが必要になります。そして、私はあなたが気づくと思います 私がこれで行くところ ;-)

TL; DR:HTTPSを使用します。信頼システムなしのクライアント側の暗号化は、暗号化をまったく行わないより安全ではありません。


ハッシュを破った後に他のサイトの共有パスワードが検出されるのではないかと心配している場合は、ハッシュと公開鍵暗号化の両方が適切です(Rainbowテーブルにより、公開鍵暗号化の方が優れています)。これらは受動的な攻撃者の計画を無効にするだけであることに注意してください。攻撃者がアクティブなMITM攻撃を仕掛けると、送信するJSコードを変更し、暗号化ビットを完全に削除できます。

8
Manishearth

これは私があなたの質問から理解していることです。

  • クライアント側でパスワードを受け入れる
  • パスワードをランダムに埋め込みます。
  • クライアントでパスワードをハッシュします。
  • サーバーの公開鍵を使用してハッシュを暗号化します
  • 暗号化されたハッシュをサーバーに送信します
  • サーバーは秘密鍵を使用してハッシュを復号化し、保存されているハッシュと比較して有効性を確認します。

ここでの問題はリプレイ攻撃です。暗号化されたハッシュを盗聴した人は誰でもそれを再利用できます。

これに対する解決策は

  1. クライアント側でパスワードに現在の時刻を追加します。次に、それをハッシュします。サーバーが取得したものを復号化すると、最初にパッケージがパスワードのハッシュと時間に分割されます。時刻が現在の時刻の+-delta以内の場合のみ、パスワードをチェックします。これにより、盗聴された暗号化ハッシュを非常に迅速に使用しない限り、再利用できなくなります。
  2. 上記のスキームを採用し、パスワード+時間文字列にID番号を追加します。そして、ハッシュなど。サーバーの責任は、特定のID番号が特定のクライアントで同じ日に再利用されないようにすることです。クライアントの責任は、同じ日に同じID番号を再利用しないことを確認することです。これにより、イベントの直後にリプレイ攻撃を防ぐことができます。

ここで非常に重要なコンポーネントの1つは、サーバーの証明書(公開キー)がクライアントに事前にインストールされている必要があることです。クライアントがサーバーに証明書を要求して証明書を取得することはできません。

3
user93353