web-dev-qa-db-ja.com

認証:1つのデータベースフィールドでハッシュされたユーザー名(メール)とパスワード

現在、PHPクライアント向けのフレームワークを備えたプラットフォームを開発しています。

クライアントのIT部門の責任者は、電子メール+パスワード+塩(ハッシュ)を含む1つのデータベースフィールドで認証を処理することを望んでいるため、このテーブルにプレーンテキストの電子メールフィールドはなく、パスワードはより安全です(その理由)。ユーザーは自分のメールアドレスとパスワードでログインできるはずです。したがって、メールアドレスはユーザー名として機能します。この背後にある考え方は、ユーザーの電子メールアドレスはクライアントのビジネスにとって非常に重要であり、ITヘッドは攻撃の可能性がある場合に備えてログインテーブルの電子メールアドレスを隠したいと考えているということです。 (例:ハッカーがログインテーブルにアクセスする)

ログイン用のハッシュ化された電子メールアドレスはプロファイルテーブルの彼の電子メールアドレスにリンクされているため、これはもちろん可能です。基本的に、このプロセスが機能するために必要な2つのテーブルがあります。テーブルはもちろん同じデータベースにあります。ハッシュの組み合わせフィールド(email、pw、salt)を持つ1つのログインテーブルと、1つのフィールドにプレーンテキストの電子メールを含む1つのプロファイルテーブル。それをprofile_emailと呼びましょう。

これまで聞いたことがなく、このソリューションで起こり得る問題をすでに特定しているため、このソリューションを使用しないことを強くお勧めします。

だから私の質問は:これは安全で実現可能な解決策ですか?予測できない問題を思いつきますか?同様の解決策を聞いたことがありますか?

6
SEoCid86

私の知る限り、このスキームは意味がありません。お気づきのように、まだユーザーのプレーンテキストの電子メールアドレスを保存する必要があるため、プレーンテキストの電子メールと電子メール+パスワード+ソルトハッシュを使用する場合と比べて、セキュリティ上の大きなメリットはありません。プレーンテキストの電子メールとパスワード+ソルトハッシュ。

既にお気づきのように、プレーンテキストのメール(プロファイルテーブルとログインテーブルのどちらにあるかを問わず)を使用して、ハッシュされた単一のメール+パスワード+ソルトの値のみに依存することは不可能です(実行する必要があります)各行を介してソルトを取得し、ハッシュを計算し、一致するかどうかを確認します。一致しない場合は、次の行からソルトを取得し、ハッシュを計算し、一致するかどうかを確認します...など)これは、攻撃者が1回のログイン試行でサイト上のすべてのユーザーのハッシュをテストできるのに対し、特定のユーザーのハッシュのみをテストできるため、セキュリティ上の問題が発生するためです。

これを行う正当な理由はないと思います。セキュリティは向上しませんが、複雑さが増し、実装には危険が伴います。丁寧に、しかししっかりとクライアントにプッシュバックして、彼自身の明確な計画を発明しようとするのではなく、標準のベストプラクティスに従うようにしてください。

12
Xander

あなたとIT部門の責任者の間に誤解がある可能性はありますか? Xanderがすでに指摘したように、そのようなスキームは機能せず、私はそれがばかげているとさえ付け加えます。ユーザーを認証するために、比較に使用される対応するハッシュを取得するために、ログイン電子メールアドレスに対してデータベースルックアップが実行されます

SELECT hash from Users WHERE email=?;
if($hash == hash_func($password)) then Grant access

現在提案しているのは、JOIN操作を追加して検索をより複雑にし、Usersテーブルでの直接検索を回避することです。

SELECT U.hash from Users U INNER JOIN Profile P WHERE P.id = U.id AND P.email=?;

sameデータベースにある2つのテーブルをクエリしても、セキュリティはまったく向上しません。また、認証プロセスがより面倒で計算コストも高くなります。

電子メールアドレスを保護する必要がある場合、認証スキームの一部として使用することはできません。この問題を解決する一般的な方法は、パスワードと組み合わせてsernameを使用することです。これにより、メールアドレスに基づいて検索を行う必要がなくなります。

SELECT hash from Users WHERE username=?;

次に、それらを保護するためにencryptメールアドレスを使用することもできます。データベースがアプリケーションとは別のサーバーでホストされている場合、データベースへのアクセスを管理するすべてのユーザーが電子メールアドレスを取得できない可能性があります。


説明をありがとう。上記の回答は、質問の3番目の段落に記載されている提案に対する回答です。以下のコメントから理解できるように、クライアントは2番目の(プロファイル)テーブルを使用する必要のない根本的に異なるアプローチを提案しました。

SELECT id from Users WHERE hash=?;

上記のスキームは、テーブル内のすべてのハッシュが[〜#〜] unique [〜#〜]であることを確認した場合にのみ機能します。ログインメールの検索は行われていないため、次のセキュリティ上の問題に対処する必要があります。

  • 個々のアカウントの総当たりを防ぐ方法
  • データベースが大きくなるときにハッシュに一致する可能性
  • ハッシュは常に実行されるため、サイトがログインページへのDDOS攻撃を処理する能力

ところで、クライアントは、ユーザーが間違ったパスワードを入力して別のユーザーとしてログインするリスクを受け入れますか?はいの場合、これを続行できます。

5