/** * Verify the password. * * @param string $password The password plain text. * @param string $hash The hashed password. * * @return boolean Verify success or not. * * @see https://github.com/ircmaxell/password_compat/blob/92951ae05e988803fdc1cd49f7e4cd29ca7b75e9/lib/password.php#L230-L247 */ public function verify($password, $hash) { if (function_exists('password_verify')) { return password_verify($password, $hash); } if (!function_exists('crypt')) { throw new \RangeException("crypt() must be loaded for Password::verify method"); } // Calculate the user-provided hash, using the salt stored with the known hash $ret = crypt($password, $hash); /* * Prevent timing attack. * * @see http://rdist.root.org/2010/07/19/exploiting-remote-timing-attacks/ * @see http://rdist.root.org/2010/01/07/timing-independent-array-comparison/ * @see http://crypto.stanford.edu/~dabo/papers/ssl-timing.pdf * @see https://www.evernote.com/shard/s12/sh/ca50fc6a-7121-4b8f-a4a7-2d6577a59195/a0b0306f8c6becd1 */ if (!is_string($ret) || CryptHelper::getLength($ret) != CryptHelper::getLength($hash) || CryptHelper::getLength($ret) <= 13) { return false; } $status = 0; $len = CryptHelper::getLength($ret); for ($i = 0; $i < $len; ++$i) { $status |= ord($ret[$i]) ^ ord($hash[$i]); } return $status === 0; }
/** * Verify the password. * * @param string $password The password plain text. * @param string $hash The hashed password. * * @return boolean Verify success or not. * * @see https://github.com/ircmaxell/password_compat/blob/92951ae05e988803fdc1cd49f7e4cd29ca7b75e9/lib/password.php#L230-L247 */ public function verify($password, $hash) { if (!function_exists('crypt')) { trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING); return false; } // Calculate the user-provided hash, using the salt stored with the known hash $ret = crypt($password, $hash); if (!is_string($ret) || CryptHelper::getLength($ret) != CryptHelper::getLength($hash) || CryptHelper::getLength($ret) <= 13) { return false; } $status = 0; $len = CryptHelper::getLength($ret); for ($i = 0; $i < $len; ++$i) { $status |= ord($ret[$i]) ^ ord($hash[$i]); } return $status === 0; }