$2y$10$OqxqwpbNkQ0KOENiNvSiFuvyh/ckL27iN5KcFOqh57vGxox7gqoUS
Jak widzisz, hash ten składa się z kilku części - być może nie przyglądałeś się temu do tej pory.
$2y$10$ - mamy tutaj informację o tym, jaki algorytm został użyty (w tym przypadku jest to blowfish z wersją y.
Później jest liczba 10, która oznacza work factor. (Domyślnie jest to 12).
Po tym ciągu jest losowo wygenerowany hash - 22 znaki, które są wg patternu: [A-Za-z0-9].
Każde zwiększenie licznika work factor powoduje dwukrotne przedłużenie czasu potrzebnego na obliczenia. Wartość ta może być w zakresie <4, 99>.
Funkcja password_verify posiadając te wszystkie dane, czyli koszt (work fator), rodzaj algorytmu i hash 22 znakowy wykonuje coś takiego:
function password_verify($password, $hash) {
if (!function_exists('crypt')) {
trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING);
return false;
}
$ret = crypt($password, $hash);
if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != PasswordCompat\binary\_strlen($hash) || PasswordCompat\binary\_strlen($ret) <= 13) {
return false;
}
$status = 0;
for ($i = 0; $i < PasswordCompat\binary\_strlen($ret); $i++) {
$status |= (ord($ret[$i]) ^ ord($hash[$i]));
}
return $status === 0;
}
Proszę bardzo: https://github.com/ircmaxell/password_compat/blob/master/lib/password.php#L225-L252