[解決済み】PHPパスワードのハッシュとソルトの安全性について
質問
現在、MD5が一部安全でないと言われています。これを踏まえて、パスワード保護にどのような仕組みを使えばよいのか教えてほしい。
この質問 パスワードの「二重ハッシュ化」は、一度だけハッシュ化するよりも安全性が低いのでしょうか? は、複数回ハッシュ化することが良いアイデアであることを示唆し、それに対して 個々のファイルに対してパスワード保護を行うには? は、ソルトを使用することを提案しています。
私はPHPを使っています。安全で高速なパスワード暗号化システムが欲しいのですが。パスワードを100万回ハッシュ化するのは安全かもしれませんが、速度も遅くなります。速度と安全性のバランスをとるにはどうしたらよいでしょうか?また、結果は一定の文字数であることが望ましいと思います。
- ハッシュ化機構はPHPで利用できること
- 安全であること
- 塩を使うことができる(この場合、どの塩も同じように良いのだろうか?良い塩を生成する方法はあるのでしょうか?)
また、データベースには2つのフィールド(例えばMD5を使ったものとSHAを使ったもの)を保存したほうがいいのでしょうか?それによって、より安全になるのでしょうか、それとも安全でなくなるのでしょうか?
安全で高速なパスワード保護メカニズムを構築するために、どのハッシュ関数を使用し、どのように良いソルトを選択すればよいかを知りたいのです。
関連する質問で、私の質問を全くカバーしていないもの。
PHPにおけるSHAとMD5の違いは何ですか?
簡単なパスワード暗号化
asp.netのキーやパスワードを安全に保存する方法
Tomcat 5.5で塩漬けパスワードを実装するには?
どのように解決するのですか?
<ブロッククオート免責事項 : この回答は2008年に書かれたものです。
それ以来、PHPは私たちに
password_hash
と
password_verify
であり、導入以来、パスワードのハッシュ化&チェック方法として推奨されています。
答えのセオリーは、やはり読み物としていいのですが。
TL;DR
注意事項
- パスワードに入力できる文字を制限しない。こんなことをするのはバカだけです。
- パスワードの長さを制限しないでください。もしユーザーがsupercalifragilisticexpialidociousを含む文章を望んだとしても、その使用を妨げないことです。
- パスワードに含まれるHTML文字や特殊文字を削除したり、エスケープしたりしないでください。
- ユーザーのパスワードは絶対にプレーンテキストで保存しないでください。
- ユーザーにパスワードをメールで送信しない ただし、相手が紛失し、一時的なものを送った場合を除く。
- パスワードの記録は絶対にしないでください。
- でパスワードをハッシュ化しない。 SHA1 やMD5、SHA256さえも。 最新のクラッカー は、それぞれ600億ハッシュ/秒、1800億ハッシュ/秒を超えることができます。
-
混ぜないでください
bcryptと
生
の出力は、hash()
の場合、16進数出力かbase64_encodeのどちらかを使用します。(これは、不正な
\0
で、これはセキュリティを著しく弱める可能性があります)。
ドス
- 可能な場合はscryptを使用し、不可能な場合はbcryptを使用してください。
- bcryptもscryptも使えない場合は、SHA2ハッシュでPBKDF2を使用します。
- データベースが侵害された場合、全員のパスワードをリセットする。
- 最低文字数は8~10文字とし、大文字1文字、小文字1文字、数字、記号を最低限必要とする。これにより、パスワードのエントロピーを向上させ、クラックを困難にすることができます。(いくつかの議論については、quot;良いパスワードとは?)
なぜパスワードをハッシュ化するのか?
パスワードのハッシュ化の目的は単純で、データベースを侵害することでユーザーアカウントへの悪意あるアクセスを防ぐことです。つまり、パスワードのハッシュ化の目的は、ハッカーやクラッカーが平文のパスワードを計算するのに多大な時間やコストをかけることによって、それを抑止することにあるのです。そして、時間/コストは最高の抑止力です。
ユーザーアカウントに堅牢なハッシュ値を設定するもう一つの理由は、システム内のすべてのパスワードを変更するのに十分な時間を確保するためです。もし、データベースが侵害された場合、そのパスワードを変更するのに十分な時間が必要です。 最低 システムをロックし、データベースのパスワードをすべて変更しない場合。
ホワイトハットセキュリティのCTO、ジェレマイア・グロスマン。 White Hat Securityブログにて記載 最近、パスワード保護のブルートフォース破壊を必要とするパスワード回復を行った後。
<ブロッククオート興味深いことに、この悪夢を体験したことで、パスワードの解読、保管、複雑さについて知らなかったことをたくさん学びました。 パスワードの複雑さよりも、パスワードの保管がなぜこれまで以上に重要なのかを理解するようになった。パスワードがどのように保存されているかがわからない場合、本当に頼りになるのは複雑さだけなのです。 パスワードや暗号のプロにとっては常識かもしれませんが、一般的な情報セキュリティやWebセキュリティの専門家にとっては、とても疑問です。
(強調)
を作るもの 良い パスワードは?
エントロピ . (ランダル氏の見解を全面的に支持するわけではありませんが)。
要するに、パスワードの中にどれだけのバリエーションがあるかというのがエントロピーです。小文字のローマ字だけのパスワードの場合、26文字しかないんです。これではバリエーションが少ない。英数字のパスワードは36文字で、より優れています。しかし、大文字と小文字、そして記号を使用すると、およそ96文字になります。文字だけよりはずっといい。問題は、パスワードを覚えやすくするために、パターンを挿入してエントロピーを減らしていることだ。おっと
パスワードのエントロピーは 近似値 を簡単に作成することができます。アスキー文字の全範囲(入力可能な約96文字)を使用すると、1文字あたりのエントロピーは6.6となり、8文字のパスワードでは、将来のセキュリティのためにはまだ低すぎます(エントロピーは52.679ビット)。しかし、良いニュースもあります。長いパスワードやユニコード文字を使ったパスワードは、パスワードのエントロピーを増加させ、解読を困難にします。
パスワードのエントロピーについては、以下のページで詳しく説明しています。 クリプトスタックエクスチェンジ というサイトがあります。また、Googleで検索してもたくさん出てきます。
コメントで@popnoodlesさんと話したのですが、@popnoodlesさんの指摘は 実施中 X個の文字、数字、記号などを使ったX個の長さのパスワードポリシーは、パスワードスキームをより予測可能にすることで、実際にエントロピーを減少させることができます。確かにそうですね。ランダムであることは、最も安全であるが、最も記憶に残らない解決策である。
私が知る限り、世界最高のパスワードを作るというのは、キャッチボールをすることなんです。記憶に残らない、予測しやすい、短すぎる、ユニコード文字が多すぎる(Windowsや携帯端末で入力しにくい)、長すぎる、などなど。そのため、パスワードはフォートノックスにあるかのように保護しなければなりません。
ベストプラクティス
Bcryptと スクリプト が現在のベストプラクティスです。 スクリプト はいずれbcryptより良くなるだろうが、Linux/Unixやウェブサーバーでの標準としての採用は見られず、そのアルゴリズムについての詳細なレビューもまだ掲載されていない。しかし、それでも、このアルゴリズムの将来は有望であることは間違いない。もしあなたがRubyを使っているのであれば scrypt gem また、Node.jsには独自の スクリプト パッケージで提供されます。PHP で Scrypt を使用するには、PHP の スクリプト エクステンションまたは Libsodium 拡張(どちらも PECL で利用可能です)。
のドキュメントを読むことを強くお勧めします。 crypt関数 bcrypt の使い方を理解したい場合、あるいは 良い ラッパー のようなものを使うか PHPASS は、よりレガシーな実装です。bcryptは最低でも12ラウンド、15から18ラウンドを推奨します。
bcryptはblowfishのキースケジュールのみを使用し、可変コスト機構を備えていることを知り、bcryptを使用することに考えを改めました。後者では、すでに高価なblowfishのキースケジュールを増やすことで、パスワードをブルートフォースするコストを増加させることができるのです。
平均的な実践
この状況はもうほとんど想像がつきませんね。 PHPASS は PHP 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のようなコストのかかる方式は非常に重要なのです。
すべての脅威や攻撃手段を予見することは不可能であるため、ユーザーを保護するために最善の努力をしなければならない アップフロント . そうしないと、手遅れになるまで攻撃されたことを見逃してしまうかもしれませんから...。 そして、あなたは責任を負うことになります。 . そのような事態を避けるためには、そもそも偏執的に行動することです。自分自身のソフトウェアを(内部的に)攻撃し、ユーザーの認証情報を盗んだり、他のユーザーのアカウントを変更したり、データにアクセスしようとしたりする。もし、自分のシステムのセキュリティをテストしないのであれば、自分以外の誰も責めることはできない。
最後に:私は暗号技術者ではありません。私が述べたことはすべて私の意見ですが、それは古き良き常識と......そして多くの読書に基づいていると思います。そして、それでも心配なら、ホワイトハット・ハッカーや暗号技術者に連絡して、あなたのコードやシステムについて彼らがどう言うかを見てみることです。
関連
-
[解決済み】メンバ関数をnullで呼び出す?
-
[解決済み】Xampp ローカルホスト/ダッシュボード
-
[解決済み】既に開始されているPHPセッション【重複あり
-
phpのAllowed memory size of 134217728 bytes枯渇問題の解決法
-
[解決済み] なぜパスワードにはStringではなくchar[]が好まれるのですか?
-
[解決済み] PHPでHTML/XMLをパースして処理する方法とは?
-
[解決済み] PHPのstartWith()関数とendsWith()関数
-
[解決済み] PHPでパスワードをハッシュ化するためにbcryptを使用するにはどうすればよいですか?
-
[解決済み] PHPでデータベースのパスワードを保護するには?
-
[解決済み] SHA-1はパスワードの保存に安全か?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】PHP定数「PHP_EOL」はいつ使うの?
-
[解決済み】 PHP 未定義関数の呼び出し
-
[解決済み】stdClassクラスのオブジェクトが文字列に変換されない。
-
[解決済み】XAMPPエラー: www.example.com:443:0 サーバー証明書に、サーバー名と一致するIDが含まれていません。
-
[解決済み】PHP フェイタルエラー。未定義の関数mssql_connect()をコールしています。
-
[解決済み] * vchiqインスタンスを開くのに失敗しました。
-
[解決済み】PHPのクラスが見つからないが、インクルードされている
-
[解決済み] PHP - ストリームを開くのに失敗しました : そのようなファイルまたはディレクトリがありません。
-
[解決済み】MySQLのカラム数が1行目の値数と一致しない【非公開
-
[解決済み] Forbidden :このサーバーの /phpmyadmin にアクセスする権限がありません。