免責事項:この回答は2008年に書かれました。
それ以来、PHP は私たちpassword_hash
に andを与えpassword_verify
、その導入以来、これらは推奨されるパスワードのハッシュとチェック方法です。
ただし、答えの理論はまだ読みやすいです。
TL;DR
してはいけないこと
- ユーザーがパスワードに入力できる文字を制限しないでください。こんなことするのはバカだけ。
- パスワードの長さを制限しないでください。ユーザーが supercalifragilisticexpialidocious を含む文を必要としている場合は、その使用を妨げないでください。
- パスワードの HTML および特殊文字を削除またはエスケープしないでください。
- ユーザーのパスワードを平文で保存しないでください。
- ユーザーがパスワードを紛失した場合を除き、ユーザーにパスワードを電子メールで送信しないでください。一時的なパスワードを送信しました。
- 決してパスワードをログに記録しないでください。
- SHA1や MD5、さらには SHA256でパスワードをハッシュしないでください。最新のクラッカーは、1 秒あたり 600 億および 1800 億のハッシュを (それぞれ) 超える可能性があります。
- bcrypt とhash()の生の出力を混在させないでください。16 進出力を使用するか、base64_encode を使用してください。
\0
(これは、セキュリティを著しく弱める可能性のあるローグが含まれている可能性のある入力に適用されます。)
ドス
- 可能な場合は scrypt を使用してください。できない場合は bcrypt を使用してください。
- SHA2 ハッシュで bcrypt または scrypt を使用できない場合は、PBKDF2 を使用します。
- データベースが侵害された場合、全員のパスワードをリセットします。
- 合理的な 8 ~ 10 文字の最小長を実装し、さらに少なくとも 1 つの大文字、1 つの小文字、数字、および記号を必要とします。これにより、パスワードのエントロピーが向上し、解読が困難になります。(議論については、「良いパスワードの条件」セクションを参照してください。)
とにかくパスワードをハッシュするのはなぜですか?
パスワードをハッシュ化する目的は単純です。データベースを侵害して、ユーザー アカウントへの悪意のあるアクセスを防止することです。したがって、パスワード ハッシュの目的は、ハッカーやクラッカーが平文のパスワードを計算するために多大な時間や費用を費やすことで、ハッカーやクラッカーを抑止することです。そして、時間とコストは、武器庫の中で最も抑止力になります。
ユーザー アカウントに適切で堅牢なハッシュが必要なもう 1 つの理由は、システム内のすべてのパスワードを変更するための十分な時間を確保するためです。データベースが侵害された場合、データベース内のすべてのパスワードを変更しない限り、少なくともシステムをロックダウンするのに十分な時間が必要です。
Whitehat Security の CTO である Jeremiah Grossman 氏は、パスワード保護を力ずくで破る必要があった最近のパスワード回復の後、White Hat Security ブログで次のように述べています。
興味深いことに、この悪夢を生き抜く中で、パスワードのクラッキング、ストレージ、複雑さについて知らなかった多くのことを学びました。パスワードの複雑さよりも、パスワードの保管が重要である理由を理解するようになりました。パスワードがどのように保存されているかがわからない場合、信頼できるのは複雑さだけです。これは、パスワードと暗号化の専門家にとっては常識かもしれませんが、平均的な情報セキュリティまたは Web セキュリティの専門家にとっては、私はそれを非常に疑っています.
(私のものを強調してください。)
とにかく良いパスワードを作るものは何ですか?
エントロピー。(ランドールの見解に完全に同意しているわけではありません。)
簡単に言えば、エントロピーとは、パスワード内の変化の量です。パスワードが小文字のローマ字のみの場合、それはわずか 26 文字です。それはたいしたバリエーションではありません。36 文字の英数字パスワードの方が優れています。ただし、記号を含む大文字と小文字を使用できるのは、およそ 96 文字です。それはただの手紙よりもはるかに優れています。1 つの問題は、パスワードを覚えやすくするためにパターンを挿入することです。これにより、エントロピーが減少します。おっとっと!
パスワードのエントロピーは簡単に概算できます。ASCII 文字の全範囲 (約 96 文字の入力可能文字) を使用すると、1 文字あたり 6.6 のエントロピーが得られますが、パスワードの 8 文字では、将来のセキュリティにはまだ小さすぎます (52.679 ビットのエントロピー)。ただし、良いニュースは、より長いパスワードや Unicode 文字を含むパスワードを使用すると、パスワードのエントロピーが実際に増加し、解読が困難になることです。
Crypto StackExchangeサイトには、パスワード エントロピーに関するより長い議論があります。優れた Google 検索でも、多くの結果が得られます。
@popnoodles とのコメントで、X 個の文字、数字、記号などを含む X 長のパスワード ポリシーを適用すると、パスワード スキームがより予測しやすくなり、実際にエントロピーを減らすことができると指摘しました。私は同意しますよ。可能な限り真にランダムなランダム性は、常に最も安全ですが、記憶に残りにくいソリューションです。
私が知る限り、世界最高のパスワードを作ることはキャッチ 22 です。記憶に残らない、予測しにくい、短すぎる、Unicode 文字が多すぎる (Windows/モバイル デバイスでは入力しにくい)、長すぎる、などのいずれかです。私たちの目的に本当に十分なパスワードはありません。フォートノックスにいました。
ベストプラクティス
Bcrypt とscryptが現在のベスト プラクティスです。Scryptはいずれ bcrypt よりも優れたものになるでしょうが、Linux/Unix または Web サーバーによる標準としての採用は見られず、そのアルゴリズムの詳細なレビューはまだ投稿されていません。それでも、アルゴリズムの将来は有望に見えます。Ruby を使用している場合は、役立つscrypt gemがあり、Node.js には独自のscryptパッケージがあります。PHP で Scrypt を使用するには、Scrypt拡張機能またはLibsodium拡張機能 (どちらも PECL で利用可能) を使用します。
bcrypt の使用方法を理解したい場合は、 crypt 関数のドキュメントを読むか、適切な ラッパーを見つけるか、よりレガシーな実装にPHPASSなどを使用することを強くお勧めします。15 から 18 ではないにしても、最低でも 12 ラウンドの bcrypt をお勧めします。
bcrypt が可変コスト メカニズムを備えたフグのキー スケジュールのみを使用することを知ったとき、bcrypt の使用についての考えが変わりました。後者を使用すると、blowfish のすでに高価なキー スケジュールを増やすことで、パスワードをブルート フォースするコストを増やすことができます。
平均的な慣行
この状況はもうほとんど想像できません。PHPASSは PHP 3.0.18 から 5.3 までをサポートしているため、考えられるほぼすべてのインストールで使用できます。また、使用している環境が bcrypt をサポートしているかどうかわからない場合に使用する必要があります。
しかし、bcrypt も PHPASS もまったく使用できないとします。じゃあ何?
環境/アプリケーション/ユーザーの認識が許容できる最大ラウンド数でPDKBF2の実装を試してください。私が推奨する最小数は 2500 ラウンドです。また、操作の再現を困難にするために使用可能な場合は、必ずhash_hmac()を使用してください。
今後の実践
PHP 5.5 で登場するのは、bcrypt での作業を抽象化する完全なパスワード保護ライブラリです。私たちのほとんどは、ほとんどの一般的な環境、特に共有ホストで PHP 5.2 および 5.3 に行き詰まっていますが、@ircmaxell は、PHP 5.3.7 と下位互換性のある今後の API 用の互換レイヤーを構築しました。
暗号化の要約と免責事項
ハッシュ化されたパスワードを実際にクラックするために必要な計算能力は存在しません。コンピュータがパスワードを「クラック」する唯一の方法は、パスワードを再作成し、パスワードを保護するために使用されるハッシュ アルゴリズムをシミュレートすることです。ハッシュの速度は、ブルート フォース攻撃の能力に比例します。さらに悪いことに、ほとんどのハッシュ アルゴリズムは簡単に並列化できるため、さらに高速に実行できます。これが、bcrypt や scrypt のようなコストのかかるスキームが非常に重要な理由です。
すべての脅威や攻撃手段を予測することはできないため、ユーザーを事前に保護するために最善を尽くす必要があります。そうしないと、手遅れになるまで攻撃されたという事実さえ見逃す可能性があります...そしてあなたは責任を負います. そのような状況を回避するには、まず妄想的に行動してください。自分のソフトウェアを (内部的に) 攻撃し、ユーザーの資格情報を盗もうとしたり、他のユーザーのアカウントを変更したり、そのデータにアクセスしたりします。システムのセキュリティをテストしなければ、自分以外の誰かを責めることはできません。
最後に: 私は暗号学者ではありません。私が言ったことはすべて私の意見ですが、たまたま古き良き常識に基づいていると思います...そして多くの読書. 可能な限り偏執的になり、侵入しにくくすることを忘れないでください。それでも心配な場合は、ホワイトハットハッカーまたは暗号学者に連絡して、コード/システムについて彼らが何を言っているかを確認してください.