ホームページ >バックエンド開発 >PHPチュートリアル >パスワードハッシュのリスクと課題
MD5は実用的な衝突を確認しており、衝突に到達するためのSHA1の確率は毎日増えています(衝突の可能性の詳細は、古典的な誕生日の問題を分析することで見つけることができるので、ハッシュアルゴリズムを適用する必要がある場合は、 SHA256、SHA512、Whirlpoolなど、より多くの出力スペース(および無視できる衝突確率)を持つもの…
それらは「擬似ランダム関数」とも呼ばれます。つまり、ハッシュ関数の出力は、真の乱数ジェネレーター(またはTRNG)と区別できないことを意味します。
ハッシュ関数の出力を効率的なアルゴリズムを使用して入力に戻すことができないという事実は、クラックできないという意味ではありません。 一般的な単語と短い文字列のハッシュを含むデータベースは、通常、単純なGoogle検索を使用して、手の届く範囲にあります。また、一般的な文字列は、辞書攻撃で簡単かつ迅速に膨らんだり、ひび割れたりすることができます。
デモンストレーションhttp://www.hash-database.net/
https://isc.sans.edu/tools/hashsearch.html
ブルートフォース攻撃を緩和するには、塩は64文字までの長さである必要がありますが、後でユーザーを認証するには、データベース内に塩をプレーンテキストに保存する必要があります。 >
しかし、1つのパスワードがクラックされたとしても、使用した可能性のあるすべてのユーザーにパスワードを自動的に提供することはありません。
良い塩を生成するには、良好な乱数ジェネレーターが必要です。 phpのrand()関数が自動的に心にポップアップした場合は、すぐに忘れてください。
random.orgのランダム性に関する優れた記事があります。 簡単に言えば、コンピューターはランダムデータを単独で 乱数がコンピューターに要求されると、通常、環境変数(日付、時刻、読み取り/書き込み、延長時間のバイト#)などのいくつかのソースから入力を取得し、それらにいくつかの計算を適用してランダムデータ。 これが、アルゴリズムによって与えられたランダムデータが擬似ランダムと呼ばれるため、真のランダムデータソースと区別することが重要な理由です。 擬似ランダム数ジェネレーター(またはPRNG)の実行中に存在する正確な条件を何らかの形で再現できる場合、元の生成数を自動的に把握します。 さらに、PRNGが適切に実装されていない場合、生成されたデータのパターンを発見することが可能です。 パターンが存在する場合、結果を予測できます。たとえば、ここに記載されているWindows上のPHPのRAND()関数の場合を考えてみましょう。 どのPHPまたはWindowsバージョンが使用されているかは明確ではありませんが、RAND()を使用して生成されたビットマップを調べることで、すぐに何か問題があることがわかります。trngの出力画像と比較:
問題はphp> = 5で対処されていますが、rand()およびmt_rand()でさえ、セキュリティ関連の目的では非常に不十分であると考えられています。
openssl_random_pseudo_bytesを使用してランダム文字列を生成するためのクイックコードサンプルです。
パスワードのストレッチングは、正しく行われた場合に効果的です
このアルゴリズムは、少なくとも1秒ですべての計算を実行するために十分に反復する必要があります(攻撃者が待たなければならないことを意味します)。
ストレッチで固定されたパスワードをクラックするために、攻撃者は次のようにする必要があります。パスワードベースのキー派生関数であるPBKDF2など、標準アルゴリズムを使用することもできます
bcrypt(crypt()functionを介して)やscrypt
<span>if (hash([provided password] + [stored salt]) == [stored hash]) then user is authenticated</span>などの時間と記憶集中アルゴリズムもあります。
ここで、$コストは作業要因であり、$塩は上記のsecure_rand()関数を使用して生成できるランダムな文字列です。
<span>Generate some string or get entry from dictionary </span><span>Concatenate with salt </span><span>Apply hash algorithm </span><span>If generated hash == hash in database then Bingo </span><span>else continue iterating</span>ワークロード係数は、ターゲットシステムに完全に依存しています。 「09」の係数から始めて、操作が約で完了するまで増やすことができます。 1秒。
PHP 5> = 5.5.0の時点で、HashingのデフォルトメソッドとしてBCRyptを使用する新しいPassword_hash()関数を使用できます。
PHPにはまだScryptのサポートはありませんが、DomblackのScryptの実装を確認できます。暗号化技術を適用するのはどうですか?
ハッシュと暗号化(または
暗号化)は、しばしば混乱する用語です。前に述べたように、ハッシュは擬似ランダム関数であり、一方、暗号化は一般に「擬似ランダム順列」
暗号化技術を正しく適用する方法に非常に注意する必要があります。暗号化アルゴリズムを機密データに適用するだけで、安全に保つのに十分であることは間違っていると考えられています。一般的なルールとして、独自の暗号化の実装を適用することを決して検討しないでください 最近、Adobeは、暗号化技術を誤って適用したため、ユーザーデータベースの大規模なデータリークがありました。 私はできるだけ簡単にして、物事を本当にシンプルに保ちます。 次のスキーマを考慮してください:
テーブルの単純なテキストの内容が次のとおりです。
さて、Adobeの誰かがパスワードを暗号化することを決めましたが、2つの大きな間違いを犯しました:
パスワードを単純に復号化することはできませんが、レコード2と7が同じパスワードを共有し、3と6を共有していることに気付くことができるデータを調べることで、単純な方法で使用される暗号化キーを知ることはできませんが…これは、パスワードヒントフィールドが作用する場所です。
レコード6ヒントは
「I'm Oneです!」「Tweak」
を使用することです。キーと調整の両方が各レコードの暗号化キーになります。利用可能な最も単純な微調整は主要なキーです。これは、定義上、テーブル内のすべてのレコードに固有のものです(使用することはお勧めしませんが、これは概念を実証するためだけです):f(key、primarykey)= key primarykey 上記の上に、暗号化キーとプライマリキーの値の両方を単に連結して最終暗号化キーを生成しますが、ハッシュアルゴリズムまたはキー派生関数を適用できます。また、主要なキーを微調整として使用する代わりに、各レコードが微調整として使用されるノンセ(塩に似ています)を生成することをお勧めします。
ユーザーテーブルに調整可能な暗号化を適用した後、次のようになりました。
もちろん、パスワードのヒントの問題はまだありますが、今では各レコードに一意の値があるため、どのユーザーが同じパスワードを使用しているかは明らかではありません。
暗号化が最良の解決策ではないことを強調したいので、多くの弱点を注入できるため、パスワードを保存するために可能であれば避けるべきです...パスワードを保存するために実証済みのソリューション(BCRYPTなど)に固執することができますが、実証済みのソリューションでさえ弱点があることに注意してください。
結論に関するよくある質問(FAQ)
パスワードのハッシュと暗号化の違いは何ですか?パスワードのハッシュと暗号化は、データの保護に使用される2つの異なる方法ですが、異なる目的を果たします。暗号化は双方向関数です。暗号化されたものは、適切なキーで復号化できます。これは、誰かが暗号化キーへのアクセスを獲得した場合、データを復号化できることを意味します。一方、ハッシュは一方向の関数であり、一方的なテキストをスクランブルしてユニークなメッセージダイジェストを作成します。入力のわずかな変更でさえ、新しいハッシュ値が古いものに似ていないように、出力に劇的な変化をもたらします。これにより、ハッシュ値から元のデータを再生することが不可能になり、パスワードを保存するためにハッシュをより安全にします。データ、パスワード、またはパスフレーズをハッシュする一方向関数への追加の入力として使用されます。塩は、ストレージ内のパスワードを保護するために使用されます。塩の主な機能は、辞書攻撃または事前に計算された虹のテーブル攻撃から防御することです。一意の塩を追加することにより、2人のユーザーが同じパスワードを持っていても、ハッシュは各ユーザーに一意になります。これは、ハッカーがハッシュ値にアクセスできる場合でも、一意の塩なしでパスワードをクラックできないことを意味します。 MD5やSHA-1のように、攻撃の影響を受けやすいです。彼らは脆弱性を知っており、最新のコンピューティング力で比較的簡単に割れることができます。たとえば、2つの異なる入力が同じハッシュ出力を生成する衝突攻撃に対して脆弱です。これにより、データの完全性が損なわれます。したがって、より高いレベルのセキュリティを提供するSHA-256やBcryptなどのより強力なハッシュアルゴリズムを使用することをお勧めします。保存されたパスワードのセキュリティ。これは、暗号化ハッシュ関数をユーザーのパスワードに塩とともに適用し、結果を何度も再ハッシュすることによって行われます。このプロセスは、パスワードをハッシュするのにかかる時間を増やします。これにより、パスワードを推測しようとする多くの迅速な試みを行うことに依存している攻撃者を阻止できます。レインボーテーブル攻撃は、攻撃者がレインボーテーブルを使用して、ハッシュされたパスワードを割るために暗号化ハッシュ関数を逆にするための事前計算テーブルを使用するハッキングの一種です。レインボーテーブルには、暗号化されたパスワードの可能なすべてのプレーンテキスト順列が含まれています。この方法は基本的なハッシュに対して効果的ですが、各パスワードにユニークな塩を追加すると、ハッシュは虹のテーブル攻撃を防ぐことができます。ハッシュアルゴリズムを秘密に保つことが重要なのはなぜですか?ハッシュアルゴリズムを秘密にしておくと、特に広く使用されているアルゴリズムでは、常に可能ではありません。優れたハッシュシステムのセキュリティは、アルゴリズムの秘密に依存していません。代わりに、ハッシュに加えられた塩の秘密とランダム性に依存しています。攻撃者が塩なしでアルゴリズムを知っていたとしても、ハッシュからパスワードを逆転させることはできません。 2番目の秘密の塩として、保存されたパスワードのセキュリティを高めるために追加されました。塩は通常、ハッシュされたパスワードの隣のデータベースに保存されますが、ペッパーは秘密に保たれ、アプリケーションコードに個別に保存されます。これは、攻撃者がペッパーなしでデータベースにアクセスできる場合でも、パスワードをクラックすることはできません。または、ハッシュアルゴリズムを変更すると、保護しているデータの感度や現在の技術状態など、いくつかの要因に依存します。経験則として、より安全なハッシュアルゴリズムが広く受け入れられている場合、または現在のアルゴリズムで脆弱性が見つかった場合、更新する時が来ました。
以上がパスワードハッシュのリスクと課題の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。