私の理解は次のとおりです。
パスワードを(データベースなどに)安全に保存するには、この目的のために設計された(低速になるように設計された(bcryptなど))ハッシュアルゴリズムを使用し、パスワードごとに一意のソルトを使用します。これにより、データベースにアクセスできる攻撃者がRainbowテーブルを使用できず、ブルートフォースの試行ごとに単純なmd5またはsha1よりも時間がかかるため、攻撃者はパスワードを回復するのが難しくなります。
プレーンテキストプロトコル(つまり、SSLではない)でパスワードを安全に認証するために、サーバーはクライアントにナンスを送信し、クライアントはパスワードとナンス(およびタイムスタンプも)を組み合わせ、ハッシュアルゴリズムを実行します。そのハッシュをサーバーに送信し、サーバーは同じアルゴリズムを実行して比較します。これにより、パスワードをプレーンテキストで送信することが回避され、サーバーが同じナンスを2回受け入れるようにだまされない限り、リプレイ攻撃が不可能になります。
問題は、これの認証部分では、サーバーが実際の平文パスワードを知っている必要があることです。したがって、#1のように安全に保管することはできません。
これで、サーバーはソルトをクライアントに送信でき、クライアントはソルトされたハッシュされたパスワードを最初に計算してから#2を実行できます。しかし、ソルトハッシュされたパスワードは実質的にプレーンテキストのパスワードになるため、実際には#1はありません。
だから私の質問は、#1と#2の両方を行う方法はありますか?
はい、可能です。説明されている2つのアルゴリズムがあります here どちらもサーバーにプレーンテキストと同等のものを保存する必要を回避します(プレーンテキストパスワードをネットワーク経由で送信する必要なしに認証を可能にします)。
Secure Remote Passwordプロトコル( wikipedia 、 Stanford )を見てください。それはクライアント側でパスワードのハッシュを使用します(お気に入りの遅いソルトハッシュを選びます)が、サーバーは「ベリファイア」だけを取得します派生元離散指数によるそのハッシュ実際の認証は、2つの乱数(1つはクライアント生成、1つはサーバー生成)、ハッシュ(クライアント側のみ)、および検証(サーバー側)を使用する非対称鍵交換によって行われます。生成されたキーを使用して残りのセッションを暗号化することを目的としていますが、単純に検証して破棄することもできます。
利点:
私が間違っている場合は修正してください。ただし、ハッシュ化されたパスワードをサーバーに保持できます。安全に保管されています。そして、ナンスを認証のソルトとして使用します。私が目にする1つの大きなことは、サーバーがこのようにプレーンテキストのパスワードを知る必要がないことです。それでも、その人が正しいパスワードを入力したことを証明できますが、平文ではなくハッシュを比較することで確認できます。このシナリオでこのパスワードがプレーンテキストになる唯一の場所は、ハッシュされる前に(2回、プレーンと既知のソルトで2回)Webブラウザーウィンドウであり、プレーンテキストではなくネットワーク経由で送信されます。
以下のシナリオを検討してください