I migrated users from Yii2 to Drupal 9, where there are password hashes like $2y$13$nhBZ37OKp27jJBLgRkFlOuL5ac8Bda5n2XIZTjKON5gKPfIcxh61y genereated by Yii2 with \Yii::$app->security->generatePasswordHash("123qweASD"))
.
I migrated them 1:1.
Migrating users - advanced password examples says:
If the source system was a PHP based application that used crypt() or password_hash(), these hashes should work as-is and they can be migrated 1:1 like in the Phpass example above .When the user logs in to your Drupal 8 site for the first time, Drupal will re-hash the password.
The password are not correct.
I tried to manually insert various hashes into the database according to this algorithm (crypt() with costFactor 13) generated in Yii2, but this also leads to a login error.
I found the following code in Yii2 (User.php).
/**
* Validates password
*
* @param string $password password to validate
* @return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
if(!$password) return false;
return Yii::$app->security->validatePassword($password, $this->password);
}
In Security.php, it uses the following code.
/**
* Verifies a password against a hash.
* @param string $password The password to verify.
* @param string $hash The hash to verify the password against.
* @return boolean whether the password is correct.
* @throws InvalidParamException on bad password/hash parameters or if crypt() with Blowfish hash is not available.
* @throws InvalidConfigException when an unsupported password hash strategy is configured.
* @see generatePasswordHash()
*/
public function validatePassword($password, $hash)
{
if (!is_string($password) || $password === '') {
throw new InvalidParamException('Password must be a string and cannot be empty.');
}
if (!preg_match('/^\$2[axy]\$(\d\d)\$[\.\/0-9A-Za-z]{22}/', $hash, $matches) || $matches[1] < 4 || $matches[1] > 30) {
throw new InvalidParamException('Hash is invalid.');
}
switch ($this->passwordHashStrategy) {
case 'password_hash':
if (!function_exists('password_verify')) {
throw new InvalidConfigException('Password hash key strategy "password_hash" requires PHP >= 5.5.0, either upgrade your environment or use another strategy.');
}
return password_verify($password, $hash);
case 'crypt':
$test = crypt($password, $hash);
$n = strlen($test);
if ($n !== 60) {
return false;
}
return $this->compareString($test, $hash);
default:
throw new InvalidConfigException("Unknown password hash strategy '{$this->passwordHashStrategy}'");
}
}
Yii 2.0.6 runs on PHP 5.6, while Drupal 9.4.5 runs on PHP 8.1.4.
How do I migrate password hashes?