PHPパスワードの安全なハッシュとソルト 質問する

PHPパスワードの安全なハッシュとソルト 質問する

現在、MD5 は部分的に安全ではないと言われています。これを考慮して、パスワード保護にどのメカニズムを使用するかを知りたいです。

この質問、パスワードを「二重ハッシュ」すると、パスワードを一度だけハッシュするよりも安全性が低くなりますか?複数回ハッシュするのが良いアイデアかもしれないことを示唆しているが、個々のファイルにパスワード保護を実装するにはどうすればよいですか?塩を使うことを提案します。

私は PHP を使用しています。安全で高速なパスワード暗号化システムが必要です。パスワードを 100 万回ハッシュすると安全になるかもしれませんが、遅くなります。速度と安全性のバランスをうまく取るにはどうすればよいでしょうか。また、結果の文字数が一定になるようにしたいです。

  1. PHPではハッシュメカニズムが利用可能でなければならない
  2. 安全でなければならない
  3. 塩を使用することができます (この場合、すべての塩は同じように良いのでしょうか? 良い塩を生成する方法はあるのでしょうか?)

また、データベースに 2 つのフィールド (たとえば、1 つは MD5 を使用し、もう 1 つは SHA を使用する) を保存する必要がありますか? これにより、安全性は高まりますか、それとも低下しますか?

十分に説明できていない場合に備えて、安全で高速なパスワード保護メカニズムを実現するために、どのハッシュ関数を使用するか、また適切なソルトを選択する方法を知りたいと思います。

私の質問を完全に網羅していない関連する質問:

PHPにおけるSHAとMD5の違いは何ですか
シンプルなパスワード暗号化
asp.net のキーとパスワードを安全に保存する方法
Tomcat 5.5でソルト付きパスワードを実装するにはどうすればよいでしょうか

ベストアンサー1

免責事項: この回答は 2008 年に書かれました。

それ以来、PHPは私たちにpassword_hashそしてpassword_verifyそして、導入以来、パスワードのハッシュとチェック方法として推奨されています。

しかし、答えの理論は依然として読む価値があります。

要約

してはいけないこと

  • ユーザーがパスワードに入力できる文字を制限しないでください。これをするのは愚か者だけです。
  • パスワードの長さを制限しないでください。ユーザーが supercalifragilisticexpialidocious を含む文章を希望する場合は、その使用を禁止しないでください。
  • パスワード内の HTML や特殊文字を削除したりエスケープしたりしないでください。
  • ユーザーのパスワードをプレーンテキストで保存しないでください。
  • ユーザーがパスワードを紛失し、一時的なパスワードを送信した場合を除き、ユーザーにパスワードを電子メールで送信しないでください。
  • いかなる方法でもパスワードを決して記録しないでください。
  • パスワードをハッシュ化しないSHA1または MD5 や SHA256 も使用できます。モダンなクラッカーそれぞれ 600 億ハッシュ/秒と 1800 億ハッシュ/秒を超えることができます。
  • 混ぜないでくださいbcryptとhash()の生の出力16 進出力を使用するか、base64_encode を使用します。(これは、不正なデータが\0含まれている可能性のある入力すべてに適用され、セキュリティが著しく弱まる可能性があります。)

すべきこと

  • 可能な場合は scrypt を使用し、できない場合は bcrypt を使用します。
  • SHA2 ハッシュで bcrypt または scrypt を使用できない場合は、PBKDF2 を使用します。
  • データベースが侵害された場合は、全員のパスワードをリセットします。
  • 8 ~ 10 文字の最小文字数を妥当な長さにし、さらに少なくとも 1 つの大文字、1 つの小文字、1 つの数字、および 1 つの記号を含めることを必須にします。これにより、パスワードのエントロピーが向上し、解読が困難になります。(議論については、「良いパスワードとは?」セクションを参照してください。)

そもそもなぜパスワードをハッシュするのでしょうか?

パスワードをハッシュ化する目的は単純です。データベースを侵害してユーザー アカウントへの悪意のあるアクセスを防ぐことです。したがって、パスワード ハッシュ化の目標は、プレーン テキスト パスワードの計算に多大な時間や費用を費やさせることで、ハッカーやクラッカーを阻止することです。そして、時間と費用は、最も効果的な抑止力です。

ユーザー アカウントに適切で堅牢なハッシュが必要なもう 1 つの理由は、システム内のすべてのパスワードを変更するのに十分な時間を確保するためです。データベースが侵害された場合、データベース内のすべてのパスワードを変更できない場合でも、少なくともシステムをロックダウンするのに十分な時間が必要です

ホワイトハット・セキュリティのCTO、ジェレミア・グロスマン氏White Hat Securityブログで述べた最近のパスワード回復では、パスワード保護をブルートフォースで破る必要がありました。

興味深いことに、この悪夢を体験する中で、私はパスワードのクラッキング、保存、複雑さについて知らなかったことをたくさん学びました。パスワードの保存がパスワードの複雑さよりはるかに重要である理由を理解するようになりました。パスワードがどのように保存されているかがわからない場合、本当に頼れるのは複雑さだけです。これはパスワードと暗号の専門家にとっては常識かもしれませんが、平均的な情報セキュリティまたは Web セキュリティの専門家にとっては、まったく疑わしいことです。

(強調は私によるものです。)

そもそも良いパスワードとは何でしょうか?

エントロピ(私はランドールの見解に全面的に賛同しているわけではない。)

簡単に言うと、エントロピーとはパスワード内のバリエーションの多さです。パスワードが小文字のローマ字だけの場合、文字数はわずか 26 文字です。これはバリエーションとしては大したことではありません。英数字のパスワードは 36 文字なので、より優れています。しかし、大文字と小文字、記号を許可すると、約 96 文字になります。これは文字だけよりはるかに優れています。1 つの問題は、パスワードを覚えやすくするためにパターンを挿入することです。これによりエントロピーが減少します。おっと!

パスワードエントロピーは近似簡単に解読できます。ASCII 文字の全範囲 (およそ 96 個の入力可能な文字) を使用すると、文字あたりのエントロピーは 6.6 になりますが、パスワードの文字数が 8 文字の場合、将来のセキュリティを考えるとまだ低すぎます (エントロピー 52.679 ビット)。ただし、良いニュースは、パスワードが長くなったり、Unicode 文字を含むパスワードを使用すると、パスワードのエントロピーが実際に増加し、解読が困難になることです。

パスワードエントロピーに関するより詳しい議論は暗号スタックエクスチェンジサイト。Google 検索をうまく使えば、たくさんの結果が見つかります。

コメントで @popnoodles と話したのですが、 X 文字、数字、記号などを含む X 文字数のパスワード ポリシーを強制すると、パスワード スキームがより予測可能になり、エントロピーが実際に減少する可能性があると指摘されました。私も同感です。可能な限り真にランダムな Randomess は、常に最も安全ですが、最も記憶に残りにくいソリューションです。

私が知る限り、世界最高のパスワードを作るのはジレンマです。覚えにくい、予測しやすい、短すぎる、Unicode 文字が多すぎる (Windows/モバイル デバイスで入力しにくい)、長すぎる、などです。私たちの目的に本当に十分なパスワードは存在しないので、パスワードをフォート ノックスにいるかのように保護する必要があります。

ベストプラクティス

Bcryptと暗号現在のベストプラクティスです。暗号いずれはbcryptよりも優れたものになるでしょうが、Linux/UnixやWebサーバーで標準として採用されておらず、そのアルゴリズムの詳細なレビューもまだ投稿されていません。しかし、それでもこのアルゴリズムの将来は有望に見えます。Rubyで作業している場合は、スクリプトジェムNode.jsには独自の暗号パッケージ。PHPでScryptを使用するには、暗号拡張機能またはリボナトリウム拡張機能(両方とも PECL で利用可能)。

ドキュメントを読むことを強くお勧めします暗号機能bcryptの使い方を理解したい場合、または良い ラッパーまたは次のようなものを使用するPHPASSよりレガシーな実装の場合、少なくとも 12 ラウンドの bcrypt を推奨します。15 から 18 ラウンドは推奨しません。

bcrypt が変動コスト メカニズムを備えた blowfish のキー スケジュールのみを使用することを知って、bcrypt の使用について考えが変わりました。後者では、blowfish のすでに高価なキー スケジュールを増やすことで、パスワードをブルート フォース攻撃するコストを増やすことができます。

平均的な実践

もうこの状況を想像することはほとんどできません。PHPASSPHP 3.0.18 から 5.3 までをサポートしているため、考えられるほぼすべてのインストールで使用できます。また、環境が bcrypt をサポートしているかどうかわからない場合に使用する必要があります。

しかし、bcrypt や PHPASS をまったく使用できない場合はどうなりますか?

実装を試してみるPDKBF2とともに最大ラウンド数環境/アプリケーション/ユーザーの認識が許容できる範囲で、最低でも2500ラウンドをお勧めします。また、ハッシュ_hmac()操作の再現を困難にするために利用可能である場合。

将来の実践

PHP 5.5では、完全なパスワード保護ライブラリこれは、bcryptを扱う際の苦労を抽象化します。ほとんどの一般的な環境、特に共有ホストでは、ほとんどの人がPHP 5.2と5.3に固執していますが、@ircmaxellは互換性レイヤーPHP 5.3.7 と下位互換性のある今後の API 用です。

暗号化の要約と免責事項

ハッシュされたパスワードを実際に解読するために必要な計算能力は存在しません。コンピュータがパスワードを「解読」する唯一の方法は、パスワードを再作成し、パスワードの保護に使用されたハッシュ アルゴリズムをシミュレートすることです。ハッシュの速度は、総当たり攻撃の能力と直線的に関係しています。さらに悪いことに、ほとんどのハッシュ アルゴリズムは簡単に並列化して、さらに高速に実行できます。これが、bcrypt や scrypt などのコストのかかるスキームが非常に重要である理由です。

すべての脅威や攻撃の手段を予見することは不可能なので、事前にユーザーを保護するために最大限の努力をする必要があります。そうしないと、攻撃を受けたという事実に気付かないまま手遅れになる可能性があり、その場合、責任を負うことになります。そのような状況を避けるには、まず被害妄想を抱くようにしてください。自分のソフトウェアを(内部的に)攻撃し、ユーザーの資格情報を盗んだり、他のユーザーのアカウントを変更したり、データにアクセスしたりします。システムのセキュリティをテストしない場合は、自分以外の誰かを責めることはできません。

最後に、私は暗号学者ではありません。私が述べたことはすべて私の意見ですが、それは古き良き常識と大量の読書に基づいていると思います。覚えておいてください。できるだけ偏執的になり、侵入をできるだけ困難にしてください。それでもまだ心配な場合は、ホワイトハット ハッカーまたは暗号学者に連絡して、コード/システムについて何と言うか聞いてください。

おすすめ記事