6

Web サイトに対してユーザーを認証する場合、ハッシュの生成と比較はデータベースと Web サイトのどちらで行うべきですか?

私の主張は、ウェブサイトはユーザーが提供したパスワード(おそらくウェブサーバーによって暗号化されたもの)をデータベースに渡す必要があるということです。次に、データベースはそれをソルトで再暗号化し、ハッシュを比較します。データベースは、ユーザーの資格情報が有効かどうかを Web サーバーに応答します。このようにして、最小限の情報がデータベースから出ていきます。基本的には「はい」か「いいえ」のどちらかであり、保存されている資格情報はありません。欠点は、データベースがより多くの作業を行う必要があることです。

もう 1 つの議論は、Web サーバーで作業を行う必要があるというものです。ここで、Web サーバーはハッシュを作成し、保存されているハッシュをデータベースに要求して比較します。この状況では、ソルトをデータベースから Web サーバーに戻して、ハッシュを作成する必要があります。ただし、Web サーバーの数が増えると作業が分担されます。

個人的には、2 番目の方法はセキュリティ リスクの可能性があると考えています。Web サーバーが侵害された場合、ソルトとハッシュがデータベースから要求され、簡単にクラックされる可能性があります。

上記の操作を実行するためのベスト プラクティスは何ですか? 私は何かを見落としていますか?

ありがとう

4

4 に答える 4

3

あなたが最初に遭遇すると思われる (そしてそれは大きな問題です) 問題は、データベースにパスワード ハッシュ関数がないことです。確かに、おそらく MD5() と SHA1() がありますが、これらは暗号化ハッシュ関数です。bcrypt() または scrypt() または PBKDF2() はありますか?

パスワード ハッシュ関数ではなく暗号化ハッシュ関数を使用すると、LinkedIn のパスワードが非常に迅速に解読される可能性があります。上記の関数のいずれかを使用しないと、ハッシュが漏洩した場合に同様に脆弱になります。


あなたのデータベースがパスワード ハッシュ アルゴリズムをサポートしていると仮定して、あなたの質問に答えていきます (単に 1 つを選択する必要があるため、bcrypt を使用します)。2 つの選択肢は次のとおりです。

データベースでのハッシュ:

$db->query("SELECT COUNT(*) FROM users WHERE username = '?' AND password = BCRYPT(?, (SELECT salt FROM user WHERE username = '?'))", $username, $password, $username);
if($row['count'] != 1)
{
  // Not authenticated.  Throw exception.
}

この場合、生のパスワードがデータベースに送信され、単純な yes または no (1 または 0) が返されます。このデータベース通信は暗号化できます。ハッシュとソルトがアプリケーションに保持されることはありません。

アプリケーションでのハッシュ:

$db->query("SELECT username, salt, password FROM users WHERE username = '?', $username);
if(bcrypt($password, $row['salt']) != $row['password'])
{
  // Not authenticated.  Throw exception.
}

この場合、ハッシュとソルトがデータベースからアプリケーションに取り込まれ、生のパスワードのハッシュと比較がそこで行われます。データベースへの通信は引き続き暗号化できます。生のパスワードがデータベース メモリに保持されることはありません。

効率のために、両方のハッシュ アルゴリズムが C (または何らかのコンパイル済み言語) で記述されており、OS によって提供される可能性があるため、同じ時間がかかると想定できます。アプリケーション ハッシュ オプションはネットワーク経由でより多くのデータを受信し、データベース ハッシュ オプションはより多くのデータを送信し、より複雑なクエリを持ちます (基本的に 2 つのクエリ、1 つはソルトを取得するため、もう 1 つは比較を行うため)。私がそのクエリを書いた方法でインデックスを使用することはできないかもしれませんが、クエリは書き直すことができます。どちらの場合も、データのサイズは 1 つの TCP パケットのままである可​​能性が高いため、速度の違いは無視できます。これは、サブクエリによるアプリケーション ハッシュ オプションの勝利と言えます。

露出用。生のパスワードは、ハッシュとソルトを合わせたものよりも機密性が高いと考えています。したがって、未加工のパスワードの公開を制限することがより安全な方法のように思われ、アプリケーションのハッシュ化がベスト プラクティスになります。

于 2012-06-15T15:14:36.757 に答える
3

パスワードを安全に保存する方法に関する非常に優れた記事がここにあります。

http://throwingfire.com/storing-passwords-securely/

于 2012-06-15T15:09:44.157 に答える
3

あなたは塩の目的を見落としています。

ソルトは、ハッシュされたパスワードに対する辞書攻撃を防ぐために使用されます。あなたのパスワードが「ピーナッツ」でハッシュが 12345 の場合、辞書内のすべての単語 (パスワードを含む) のハッシュのリストを事前に生成し、事前に生成されたパスワードのセットに対してルックアップを実行して、パスワードをすばやく見つけることができます。ハッシュ。これは、LinkedIn に最近起こったことです。パスワードがソルト化されている場合、データベースを侵害した、ソルト値ごとに辞書を事前に生成する必要がありますが、これには法外なコストがかかります。

さらに、適切にランダムに生成されたソルトは、攻撃者があなたと私が同じパスワードを持っていることを知ることを防ぎます (ソルトがなければ、同じハッシュを持つことになります)。

私の要点は、塩は秘密にするつもりはないということです. これらは公開情報ではありませんが、攻撃者がソルト値とハッシュにアクセスしたからといって、必ずしもパスワードが侵害されたとは限りません。

于 2012-06-15T15:10:50.110 に答える
0

コンピュータ セキュリティの経験則として、質問する必要がある場合は、自分で行うべきではありません。ただし、Web サーバーが侵害された場合にパスワードの詳細が公開されることが懸念される場合は、認証を独自のシステムに移動し、Web サーバーにパスワード データベースへのアクセスをまったく許可しないという方法があります。

于 2012-06-15T15:19:30.233 に答える