web-dev-qa-db-ja.com

ユーザー情報とユーザーログインとパスワードを最適に保存する方法

私はMysqlを使用していますが、ユーザーの個人情報とログイン名とパスワードを2つの異なるテーブルに分け、それらを参照するだけの方が良いと考えていました。

:私の投稿を明確にするために、パスワードを保護する技術(ハッシュ、ソルトなど)を理解しています。人生の他の部分(投資、データバックアップ、個人用ストレージなど)の慣行に従っている場合、最悪のシナリオ(テーブルまたは火災を含む)で、テーブル間で情報が分割されると、追加データ。

30
Tim

パスワードを保存しないでください。ディスク上に座っていると、盗まれることがあります。代わりに、パスワードハッシュを保存します。 正しいハッシュアルゴリズムを使用 、bcrypt(ソルトを含む)のように。

[〜#〜] edit [〜#〜]:OPは、上記の問題を理解していると回答しました。

ログインとは物理的に異なるテーブルにパスワードを保存する必要はありません。 1つのデータベーステーブルが危険にさらされた場合、同じデータベース内の別のテーブルにアクセスすることは大きな飛躍ではありません。

セキュリティとセキュリティの詳細について十分に懸念している場合は、ドメインデータとは完全に別のデータストアにユーザー資格情報を保存することを検討してください。一般的に行われている1つのアプローチは、LDAPディレクトリサーバーに資格情報を保存することです。これは、後で行うシングルサインオン作業にも役立ちます。

38

パスワードは暗号化ハッシュとして保存する必要があります。暗号化ハッシュは、プレーンテキストの読み取りを妨げる不可逆的な操作です。ユーザーを認証するとき、パスワード入力は同じハッシュプロセスを受け、ハッシュが比較されます。

MD5やSHA1などの高速で安価なハッシュの使用は避けてください。目的は、攻撃者が(ハッシュの衝突に基づいて)レインボーテーブルを計算するのを高価にすることです。高速ハッシュはこれに対抗します。高価なハッシュを使用しても、1回のハッシュの実行には影響しないため、認証シナリオでは問題になりません。

ハッシュに加えて、ランダムに生成された値でハッシュをソルトします。ナンス。データベースに保存され、ハッシュの前にデータと連結されます。これにより、衝突の計算時に生成する必要のある可能な組み合わせの数が増加し、レインボーテーブルの生成の全体的な時間の複雑さが増加します。

パスワードハッシュ列は固定長にすることができます。暗号化ハッシュは、すべてのハッシュで同じになる固定長にエンコードできる値を出力する必要があります。

可能な限り、独自のパスワード認証メカニズムを使用しないでください。 bcryptなどの既存のソリューションを使用します。

パスワードを処理する方法、および自分が心配する必要があることの優れた説明は、 http://www.matasano.com/log/958/enough-with-the-Rainbow-tables-にあります。セキュアパスワードスキームについて知っておく必要があるもの

最後の注意として、攻撃者がデータベースへのアクセスを取得した場合、差し迫った懸念は、おそらくアクセスする可能性のある機密情報または個人を特定する情報、および彼らが行った損害に関するものであることを忘れないでください。

18
Rob

それらを同じテーブルに置いても何も問題はありません。実際、はるかに高速になるので、強くお勧めします。なぜあなたはそれを分割したいのか分かりません。

14
Sasha Chedygov

元の質問に答えようとします。収集する個人情報がたくさんある場合を除き、すべてを1つのテーブルに収めることは問題ありません。その場合、それを分割することは理にかなっているかもしれません。その決定は、取り扱っている個人情報の量と、アクセスする必要がある頻度に基づいて行う必要があります。

ほとんどの場合、1つのテーブルでこのようなことをします。

UserID, FirstName, LastName, Email, Password, TempPassword

しかし...それ以上のものを集めている場合。電話、ファックス、生年月日、伝記などを収集しているとします。その情報のほとんどがめったにアクセスされない場合は、おそらくそれを独自のテーブルに入れて、1対1の関係で接続します。結局のところ、テーブルにある列が少ないほど、そのテーブルに対するクエリは高速になります。そして、時々、最もアクセスされるテーブルを単純化することが理にかなっています。その個人情報にアクセスする必要があるときはいつでも、JOINでパフォーマンスが低下します。そのため、考慮する必要があります。

編集-あなたは何を知っている、私はちょうど何かを考えた。ユーザー名または電子メールフィールド(どちらでもかまいません)にインデックスを作成すると、ユーザーテーブルに非常に多くの列を作成することによるパフォーマンスの低下がほぼ完全になくなります。なぜなら、もしインデックスがあれば、WHERE句はログインするたびにユーザー名を見つけるのに非常に迅速になり、そのテーブルに100個のカラムがあっても関係ないからです。 だから私の意見を変えました。すべてを1つのテーブルに入れました。;)

どちらの場合でも、セキュリティは一般的なトピックのようであるため、パスワードはハッシュ値にする必要があります。 SHA1(またはあなたが本当に心配している場合はSHA256)をお勧めします。 TempPasswordはハッシュも使用する必要があり、パスワードを忘れた場合にのみ使用できます。明らかにハッシュでは、復号化してユーザーに元のパスワードを送信することはできません。そのため、代わりにログインできる一時的なパスワードを生成し、ログイン後に再度パスワードの変更を強制します。

8
Steve Wortham

このデータはすべて、ユーザーと常に1対1の関係にありますか?ユーザーが複数の住所や電話番号などを持つことを許可することを予見できる場合は、個人情報を別のテーブルに分割することができます。

4
dkaylor

最初に、(願わくば)明白なことを述べるために、もし何らかの方法でユーザー名とパスワードを保存することを避けることができるなら、そうするようにしてください。それは大きな責任であり、資格情報ストアが侵害された場合、同じユーザーが他の多くの場所にアクセスできるようになる可能性があります(パスワード共有のため)。

資格情報を保存する必要がある場合:

  • リバーシブルフォームを保存しないでください。 SHA-256などの認識されたアルゴリズムを使用してハッシュを保存します。信頼できる信頼できるソースからの暗号化ソフトウェアを使用してください-自分を転がそうとしないでください。間違ってしまう可能性があります。
  • 資格情報セットごとに、ハッシュされたデータとともにソルトを保存します。これは、2つの同一のパスワードが同じハッシュを生成しないようにハッシュを「準備」するために使用されます。これにより、パスワードが同じであることがわかります。
  • 安全なランダムジェネレーターを使用します。弱いランダム性は、暗号アルゴリズムではなく、暗号化に関連するセキュリティ障害の最大の原因です。

reversibleクレデンシャルを保存する必要がある場合:

  • 適切な暗号化アルゴリズム-AES-256、3DES(日付)、または公開キー暗号を選択してください。信頼できる信頼できるソースからの暗号化ソフトウェアを使用してください-自分を転がそうとしないでください。間違ってしまう可能性があります。
  • 資格情報セットごとに、暗号化されたデータとともにソルト(暗号化されていない)を保存します。これは、2つの同一のパスワードが同じ暗号文を生成しないように暗号化暗号を「準備」するために使用されます。これにより、パスワードが同じであることがわかります。
  • 安全なランダムジェネレーターを使用します。弱いランダム性は、暗号アルゴリズムではなく、暗号化に関連するセキュリティ障害の最大の原因です。
  • 暗号化/復号化キーをデータベースとは別に、アプリケーションランタイムプロファイルのみがアクセスできるO/Sで保護されたファイルに保存します。そのように、DBが(たとえば、SQLインジェクションを介して)侵害された場合、一般にHDDへのアクセスが必要になるため、キーは自動的に脆弱ではありません。 O/Sがプロファイルに関連付けられたファイル暗号化をサポートしている場合、それを使用します-それは役立つだけであり、一般に透過的です(例:NTFS暗号化)。
  • 実用的な場合は、キー自体をプライマリパスワードで暗号化して保存します。これは通常、アプリを意味します。起動時にパスワードを入力する必要があります。HDDに違反した場合、キーファイルとスクリプトの両方を表示できると想定する必要があるため、スクリプトからパラメータで指定するのはよくありません。
  • アカウントレコードの検索にユーザー名が不要な場合は、ユーザー名とパスワードの両方を暗号化します。
3
Lawrence Dol

私の個人的な経験では、個人情報とログイン情報を個々のデータベースに保存することがこの場合のベストプラクティスです。 SQLインジェクションが行われるべき理由は、データの集合体全体へのアクセスを提供するのではなく、データが関係するテーブルに限定されます(データベースの内部レイアウトを知らない限り)。

ただし、これにより多くのクエリを実行する必要があるため、パフォーマンスが低下する可能性があることに注意してください。

2
Jason

それらを同じテーブルに保存し、一方向暗号化を使用する必要があります。 MD5は機能しますが、弱いため、SHA1または別の方法を検討することをお勧めします。 2つのアイテムを別々のテーブルに保存してもメリットはありません。

0
Ben Lakey