PHP function password_verify()
に関して、ハッシュ関数が決定論的であるとすると、「ハッシュされていない」ランダムソルトはpassword_hash()
の出力からどのように導出されますか?元のソルトが最終ハッシュから導出できる場合、ハッシュ関数が反復回数を完了した後にのみソルトが最終ハッシュを生成するために使用されたように思えます。これが当てはまる場合、ソルトを使用する理由そもそもなぜですか?
password_hash
とpassword_verify
は現在bcrypt
またはargon2
のどちらかを使用します。どちらも PHC文字列形式 を使用します。ソルトはハッシュ形式に含まれています。これはpassword_verify
から派生したものではなく、文字通り、与えられたハッシュ内のまさにその場所にあります。塩は秘密である必要はないため、これは弱点ではなく、普遍的に一意である必要があります。
password_verify
がソルトを取得する方法についての混乱は、用語の矛盾が原因であると思われます。 「ハッシュ」という単語は、PHC形式の文字列全体(ハッシュ関数の識別子、パラメーター、ソルト、実際のハッシュ値を含む)や、ハッシュ関数によって出力される実際のハッシュを表すためによく使用されます。
塩が使用される理由については here を参照してください。攻撃者がパスワードをハッシュするために知っておく必要のある秘密が必要な場合、それは pepper と呼ばれます。
PHPの内部で何が起こっているかを示す、この極端な単純化を見てください。
password_hash(password):
salt = get_random_salt()
hash = actual_hashing_function(salt + password)
return salt + hash
password_verify(password, password_hash):
salt, actual_hash = split(password_hash)
compare_hash = actual_hashing_function(salt + password)
return actual_hash == compare_hash
ご覧のとおり、password_hash
は出力の一部として確定的ではありません-salt-はランダム関数に依存しています。ただし、actual_hashing_function
は確定的です。
ここでの混乱は、やや不正確な用語に起因しています。暗号化のコンテキストでは、「ハッシュ関数」はおそらく例のactual_hashing_function
のようなものを指し、「ハッシュ」は出力であることを意味します。ただし、プログラミングなどのより適用されたコンテキストでは、「ハッシュ関数」はpassword_hash
のようなものを意味し、「ハッシュ」はソルトを含む非決定的な出力です。