the PHP manual のこの例では、実行するたびに異なる結果が出るのはなぜですか?
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
そして、password_verify()は、これらすべてのハッシュが「rasmuslerdorf」に一致することを認識します。医者がはっきり言ったとしても、それは私にとって魔法のようです:
Password_hash()は、返されたハッシュの一部としてアルゴリズム、コスト、ソルトを返すことに注意してください。したがって、ハッシュを検証するために必要なすべての情報が含まれています。これにより、ソルトまたはアルゴリズム情報用の個別のストレージを必要とせずに、検証機能でハッシュを検証できます。
この機能はタイミング攻撃に対して安全です。
echo password_verify ( 'rasmuslerdorf' , '$2y$10$EMawXU7qNS4GzU2Do8bByeb7sSQZxecvmZ6mBrToxsOaY7RMAIGua' ); //=>true
echo password_verify ( 'rasmuslerdorf' , '$2y$10$0vMA2k7LxTBstI/J7clkkuZZ/XtuS1fklVuoM6sl4Fc/aj1avQa5u' ); //=>true
echo password_verify ( 'rasmuslerdorf' , '$2y$10$iuE2EzHMNONAWFKh/4Wyl.dcBxgFaNzAh32va0/gyE4ScqnNr/Uc.' ); //=>true
何が起こっている?どのようにpassword_verify()は、いくつかのクレイジーな文字列の一致が「rasmuslerdorf」であることを知っていますが、ハッカーはそうではありませんか?
password_hash
関数は、内部的に次の手順を実行します。
#1のランダムな選択が、同じ入力を提供しても毎回異なる出力を生成する理由です。ステップ#3からのフォーマット済み出力は、password_verify
がpassword_hash
によって選択されたランダムなソルトを認識できるようにするものです。
有用な暗号化ハッシュを作成する鍵は、アルゴリズムを不可逆にすることですが、一貫して繰り返し可能にする必要があります。あれは:
password_hash('rasmuslerdorf')
の出力だけでは、文字列_'rasmuslerdorf'
_を取得できません'rasmuslerdorf'
_が与えられると、password_hash('rasmuslerdorf')
への以前の呼び出しと同様に同じ出力を生成できますこれにより、パスワードを取得することなく、ハッシュに対するユーザーのパスワード試行をチェックできます。
繰り返し可能なハッシュを取得する最も簡単な方法は、入力のみに依存することです。したがって、password_hash('rasmuslerdorf')
は常に同じ値を返します。しかし、これは攻撃者が一連の一般的なパスワードのハッシュを計算し、盗まれたデータベースで一致するものを検索できることを意味します。
したがって、代わりに、優れたハッシュアルゴリズムはsaltを追加します。これは、ランダムな文字列をパスワードに追加しただけで、毎回ハッシュを変えることができます。後でハッシュ関数を繰り返してsameの回答を得るには、保存時に使用されたソルトを知る必要があります。
これは_password_hash
_が実際に出力するもので、1つの文字列に結合されます。
この出力は毎回異なるため、同じ答えが得られるかどうかを確認するには、ユーザーの入力でハッシュを繰り返すdifferent関数が必要です。これが_password_verify
_の目的です。
同じアルゴリズムを同じオプションとハッシュで実行すると、結果が異なる場合、ユーザーは間違ったパスワードを入力した必要があります。