データベースにパスワードを保存する好ましい方法
-
03-07-2019 - |
質問
パスワードをデータベース(好ましくはSQL Server 2005)に保存するための望ましい方法/データ型は何ですか。いくつかのアプリケーションでこれを行っている方法は、最初に.NET暗号化ライブラリを使用し、次にそれらをbinary(16)としてデータベースに保存することです。これは好ましい方法ですか、別のデータ型を使用するか、16より多くのスペースを割り当てる必要がありますか?
解決
パスワードに相当するソルトハッシュをデータベースに保存し、パスワード自体は保存せず、ハッシュとユーザーが渡したものの生成されたものを常に比較します。
文字通りのパスワードデータをどこにでも保存するのは非常に危険です。これにより回復が不可能になりますが、誰かがパスワードを忘れたり紛失したりすると、いくつかのチェックを実行して新しいパスワードを作成できます。
他のヒント
推奨される方法:パスワードをデータベースに保存しないでください。ハッシュのみ。塩を味に加えます。
文字列として保存されることを除いて、あなたが説明したのと同じことをします。 I暗号化されたバイナリ値をBase64エンコードします。割り当てるスペースの量は、暗号化アルゴリズム/暗号強度によって異なります。
正しく実行していると思います( Salt を使用している場合) 。
- bcrypt(nounce + pwd)などのソルトパスワードのハッシュを保存します。 CPUを集中的に使用するように調整できるため、SHA1またはMD5よりもbcryptを好む場合があります。したがって、ブルートフォース攻撃の方法が長くなります。
- いくつかのログインエラーが発生した後、ログインフォームにキャプチャを追加します(ブルートフォース攻撃を回避するため)
- アプリケーションに「パスワードを忘れた場合」がある場合リンク、電子メールで新しいパスワードを送信しないことを確認しますが、代わりに、ユーザーが新しいパスワードを定義できるようにする(セキュリティで保護された)ページへのリンクを送信する必要があります(おそらく、ユーザーの出生などの個人情報の確認後にのみ)日付など)。また、アプリケーションでユーザーが新しいパスワードを定義できる場合は、ユーザーに現在のパスワードの確認を要求するようにしてください。
- そして明らかに、ログインフォーム(通常HTTPSを使用)とサーバー自体を保護します
これらの対策により、ユーザーのパスワードは以下に対してかなりよく保護されます:
- =>オフライン辞書攻撃
- =>ライブ辞書攻撃
- =>サービス拒否攻撃
- =>あらゆる種類の攻撃!
ハッシュ関数の結果は0から255(または8ビットのデータ型の符号付き度に応じて-128から127)の一連のバイトであるため、生のバイナリフィールドとして保存します最もコンパクトな表現であり、追加のエンコードおよびデコード手順を必要としないため、最も意味があります。
一部のデータベースまたはドライバーは、バイナリデータ型を十分にサポートしていないか、開発者がそれらに慣れていないことがあります。その場合、Base-64やBase-85のようなバイナリからテキストへのエンコーディングを使用し、結果のテキストを文字フィールドに保存することができます。
必要なフィールドのサイズは、使用するハッシュ関数によって決まります。 MD5は常に16バイトを出力し、SHA-1は常に20バイトを出力します。ハッシュ関数を選択すると、変更するには既存のすべてのパスワードをリセットする必要があるため、通常はその関数に固執しています。したがって、可変サイズのフィールドを使用しても何も買えません。
「最高」についてハッシュを実行する方法、私はそのトピックに関する他のSOの質問に多くの答えを提供しようとしました:
ユーザー名のshaハッシュ、web構成のguid、およびvarchar(40)として保存されているパスワードを使用します。彼らがブルートフォース/ディクショナリを希望する場合は、GUIDのWebサーバーもハッキングする必要があります。ユーザー名がパスワードを見つけた場合、データベース全体にレインボーテーブルを作成することはできません。ユーザーがユーザー名を変更したい場合は、パスワードを同時にリセットするだけです。
System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(
username.ToLower().Trim(),
ConfigurationManager.AppSettings("salt"),
password
);
パスワードの単純なハッシュ、または(塩+パスワード)は一般に適切ではありません。
参照:
and
http://gom-jabbar.org/articles/2008/12/03/why-you-should-use-bcrypt-to-store-your-passwords
bcryptアルゴリズムを推奨します。無料の実装は、ほとんどの一般的な言語でオンラインで見つけることができます。
データベースで複数のハッシュを使用できますが、少しだけ余分な労力が必要です。ただし、将来的に追加のフォーマットをサポートする必要がある可能性が最も低いと思われる場合は、それだけの価値があります。次のようなパスワードエントリをよく使用します
{hashId} $ {salt} $ {hashed password}
where" hashId"は、たとえば、特定のハッシュパターンでSHA1を使用していることを認識するために、内部的に使用している数字です。 " salt" base64でエンコードされたランダムソルトです。および「ハッシュ化されたパスワード」 base64でエンコードされたハッシュです。ハッシュを移行する必要がある場合は、古いパスワード形式のユーザーを傍受し、次回ログインするときにパスワードを変更させることができます。
他の人が言ったように、本当に安全ではない何かをするのは簡単だから、あなたはハッシュに注意したい。例えば、H(salt、password)はH(password、salt)よりもはるかに弱いが、同時にこれに費やされる労力とサイトコンテンツの価値のバランスを取る必要があります。私はよくH(H(password、salt)、password)を使用します。
最後に、base64でエンコードされたパスワードを使用するコストは、テキストデータを期待するさまざまなツールを使用できる利点と比較すると、控えめです。ええ、彼らはより柔軟でなければなりませんが、レコードごとに数バイトを節約したいので、彼がお気に入りのサードパーティのツールを使用できないことを上司に伝える準備はできていますか? :-)
他のコメントを追加するために編集しました。各パスワードを1/10秒もハッシュするアルゴリズムを意図的に使用することを提案した場合、上司のオフィスから笑い出されるだけで幸運です。 (それほど幸運ではありませんか?彼は私の次の年次レビューで議論するために何かを書き留めるでしょう。)その時間を燃やすことは、あなたが数十、あるいは数百のユーザーを持っているとき、問題ではありません。 10万人のユーザーをプッシュする場合、通常は同時に複数のユーザーがログインします。遅くて強いものではなく、速くて強いものが必要です。 「ただし、クレジットカード情報はどうなりますか?」保存されたクレジットカード情報は通常のデータベースの近くにあるべきではなく、とにかく個々のユーザーではなくアプリケーションによって暗号化されるため、せいぜい不誠実です。
ASP.Netを使用している場合は、組み込みのメンバーシップAPIを使用できます。
これは、多くのタイプのストレージオプションをサポートしています。一方向ハッシュ、双方向暗号化、md5 + salt。詳細については、 http://www.asp.net/learn/security を参照してください。
>あまり凝ったものが必要ない場合、これはウェブサイトに最適です。
ASP.Netを使用していない場合は、4guysとcodeprojectの記事へのリンクがあります
http://aspnet.4guysfromrolla.com/articles/081705-1.aspx http://aspnet.4guysfromrolla.com/articles/103002-1.aspx http://www.codeproject.com/KB/security/SimpleEncryption.aspx
質問は保存方法と&サイズに対処します。
ストレージタイプは、バイナリ表現またはテキスト表現のいずれかです(base64が最も一般的です)。バイナリは小さくなりますが、テキストの操作は簡単です。ユーザーごとのソルティング(パスワードごとに異なるソルト)を実行している場合、salt + hashを単一の結合文字列として保存する方が簡単です。
サイズはハッシュアルゴリズムに依存します。 MD5の出力は常に16バイト、SHA1は常に20バイトです。 SHA-256& SHA-512は32&それぞれ64バイト。テキストエンコードを使用している場合、エンコード方法に応じてわずかに多くのストレージが必要になります。ストレージは比較的安価なので、Base64を使用する傾向があります。 Base64では、約33%大きいフィールドが必要になります。
ユーザーごとのソルティングがある場合は、ハッシュ用のスペースも必要になります。 64ビットソルト+ SHA1ハッシュ(160ビット)base64エンコードをすべてまとめると40文字かかるため、char(40)として保存します。
最後に正しく実行したい場合は、単一のハッシュを使用するのではなく、RBKDF2のようなキー派生関数を使用する必要があります。 SHA1およびMD5ハッシュは非常に高速です。シングルスレッドアプリケーションでも、クアッドコアマシンでは1秒あたり約30K〜50Kのパスワードをハッシュできます。 GPUは、1秒あたり100倍から1000倍のパスワードをハッシュできます。このような速度では、ブルートフォース攻撃が許容される侵入方法になります。 RBKDF2では、反復の数を指定して、「遅い」方法を微調整できます。あなたのハッシングは。ポイントは、システムをひざまずかせることではなく、ハッシュスループットの上限(たとえば、1秒あたり500ハッシュ)を抑えるために、何度も繰り返しを選択することです。将来の証明方法は、パスワードフィールドに反復回数を含めることです(反復+ソルト+ハッシュ)。これにより、将来の反復回数が増え、より強力なプロセッサに対応できるようになります。さらに柔軟にするには、varcharを使用して、将来的にはより大きな/代替のハッシュを使用できるようにします。
.Net実装はRFC2892DeriveBytesです http://msdn.microsoft.com/en-us /library/system.security.cryptography.rfc2898derivebytes.aspx