PHP 8.4.0 RC4 available for testing

password_needs_rehash

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

password_needs_rehash指定したハッシュがオプションにマッチするかどうかを調べる

説明

password_needs_rehash(string $hash, string|int|null $algo, array $options = []): bool

指定したハッシュが、特定のアルゴリズムとオプションを満たしているかどうかを調べます。 満たしていない場合は、ハッシュを再計算する必要があるとみなします。

パラメータ

hash

password_hash() が作ったハッシュ。

algo

パスワードのハッシュに使うアルゴリズムを表す パスワードアルゴリズム定数

options

オプションを含む連想配列。各アルゴリズムがサポートするオプションについては、 パスワードアルゴリズム定数 のページを参照ください。

戻り値

指定した algooptions にマッチするためにハッシュの再計算が必要な場合は true、 それ以外の場合は false を返します。

変更履歴

バージョン 説明
7.4.0 algo パラメータは string を期待するようになりました。 しかし、後方互換性のために int も未だ受け入れています。

例1 password_needs_rehash() の使用例

<?php

$password
= 'rasmuslerdorf';
$hash = '$2y$10$YCFsG6elYca568hBi2pZ0.3LDL5wjgxct1N8w/oLR/jfHsiQwCqTS';

$algorithm = PASSWORD_BCRYPT;
// bcrypt の cost パラメータは、ハードウェアの性能の向上にあわせて変えることができます
$options = ['cost' => 12];

// 格納されたハッシュを、平文のパスワードに対して検証します
if (password_verify($password, $hash)) {
// ハッシュアルゴリズムやオプションが変更されたかを確認します。
if (password_needs_rehash($hash, $algorithm, $options)) {
// 変更された場合は新しいハッシュを計算して、古いものを置き換えます
$newHash = password_hash($password, $algorithm, $options);

// ユーザーのレコードを $newHash で更新します
}

// ログイン
}
?>

add a note

User Contributed Notes 3 notes

up
27
php dot net at muer dot nl
10 years ago
This function cannot check if a string is a MD5 or SHA1 hash. It can only tell you if a password, hashed using the password_hash function, needs to be put through the hashing function again to keep up to date with the new defaults.

The only time you can use this function is when your user logs in and you have already checked by means of password_verify that the password entered is actually correct. At that point, if password_needs_rehash returns true, you can put the plain text password through the password_hash function.
up
11
geekasylum at google mail
6 years ago
This function can indeed be used to assist in transparently updating legacy passwords (those not using the password_hash() function - eg: perhaps something using MD5 or SHA1)

In legacy sites, when authenticating a user (during login) first check the password using password_verify(). If that fails it may simply be because the user's password hash was created long ago by a legacy or home-brew password algorithm.

You can then re-check the password against the site's legacy password algorithm. If that fails too, then the login fails, since the supplied password did not authenticate against either the new, or the old password tests.

If any one of those two test was successfull, you know that the password is good so you would then call password_needs_rehash() on the stored hash, and it will properly indicate if the password hash needs to be re-computed, either because it's an unrecognised (legacy) hash or it's a modern hash created by password_hash(), which may just need its cost index updated.

Simply store the recomputed hash in the database and you now have a password_verify() compatible password for that user and the second test can be skipped in future logins (but still check if it needs rehashing).
up
13
admin at torntech dot com
10 years ago
Some other use-cases for the password_needs_rehash function is when you have specified using the PASSWORD_DEFAULT algorithm for password_hash.
As mentioned on the Password Hashing Predefined Constants and password_hash pages, the algorithm used by PASSWORD_DEFAULT is subject to change as different versions of PHP are released.
Additionally password_needs_rehash would be used if you have changed the optional cost or static salt (DO NOT USE A STATIC SALT) requirements of your password_hash options.

Full example:

<?php

$new
= [
'options' => ['cost' => 11],
'algo' => PASSWORD_DEFAULT,
'hash' => null
];

$password = 'rasmuslerdorf';

//stored hash of password
$oldHash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';

//verify stored hash against plain-text password
if (true === password_verify($password, $oldHash)) {
//verify legacy password to new password_hash options
if (true === password_needs_rehash($oldHash, $new['algo'], $new['options'])) {
//rehash/store plain-text password using new hash
$newHash = password_hash($password, $new['algo'], $new['options']);
echo
$newHash;
}
}
?>

The above example will output something similar to:
$2y$11$Wu5rN3u38.g/XWdUeA6Wj.PD.F0fLXXmZrMNFyzzg2UxkVmxlk41W
To Top