これを解決するにはさまざまな方法がありますが、今思いつく最も簡単な方法は、何らかのチャレンジを使用することです。サーバーは、クライアントがソルトとして使用する必要がある値を送信します。サーバーは、値が一意であること、有効期限が切れていないこと、および 1 回だけ使用されることを保証します (これにより、リプレイ攻撃が不可能になります)。
これにより、プレーン テキストのパスワードは送信されず、ハッシュ化されたパスワードのみが送信されるようになります。「ワンタイムソルト」でハッシュを計算するにはクリアテキストパスワードが必要であるため、サーバーはクライアントを信頼できます(とにかくプレーンテキスト認証を行うときと同じくらい信頼します)。
もう 1 つのより洗練された (そして安全な) 方法は、サーバーが公開鍵を持ち、クライアントが秘密鍵を持つパスワードから RSA キーペアを生成することです。クライアントは、サーバーの公開鍵のコピーも持っています。ユーザーがパスワードを入力すると、正しいパスワードのみが正しい rsa-key を取得します。
次に、ユーザーはサーバーの公開鍵でリクエストを暗号化し、ユーザーの秘密鍵でリクエストに署名します。その後、サーバーのみが要求を復号化でき、サーバーはユーザーの公開鍵で署名を検証することにより、送信者が本当に正しいユーザーであることを検証できます。そして、応答の反対。セキュリティを追加するには、以前に書いたように、リプレイ攻撃が不可能であることを確認するために、独自の「ソルト」を追加する必要があります。