Upgrading Hashing Algorithms from CakePHP 2.5.3 to 4.2.1

Hello,

I have to upgrade app from cakephp 2 to 4 and I follow cake documentation, but get error messages:

Argument 2 passed to Authentication\PasswordHasher\FallbackPasswordHasher::check() must be of the type string, resource given, called in /vagrant/vendor/cakephp/authentication/src/Identifier/PasswordIdentifier.php on line 131

CakePHP 2.5.1 password hasher

public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
		$passwordHasher = new BlowfishPasswordHasher();
		$this->data[$this->alias]['password'] = $passwordHasher->hash(
			$this->data[$this->alias]['password']
		);
}
return true;
}

@CakePHP 4.2 Applications

public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
    {
        $authenticationService = new AuthenticationService([
            'unauthenticatedRedirect' => '/users/login',
            'queryParam' => 'redirect',
        ]);

        // Load identifiers, ensure we check email and password fields
        $authenticationService->loadIdentifier('Authentication.Password', [
            'fields' => [
                'username' => 'username',
                'password' => 'password',
            ],
            'resolver' => [
                'className' => 'Authentication.Orm',
            ],
            'passwordHasher' => [
                'className' => 'Authentication.Fallback',
                'hashers' => [
                    'Authentication.Default',
                    [
                        'className' => 'Authentication.Legacy',
                        'hashType' => 'md5',
                        //'salt' => false, // turn off default usage of salt
                    ],
                ],
            ],
        ]);

        // Load the authenticators, you want session first
        $authenticationService->loadAuthenticator('Authentication.Session');
        // Configure form data check to pick email and password
        $authenticationService->loadAuthenticator('Authentication.Form', [
            'fields' => [
                'username' => 'username',
                'password' => 'password',
            ],
            'loginUrl' => '/users/login',
        ]);

        return $authenticationService;
    }

How to fix?

I had a similar situation, just grab the input password in request and recreate using new hash.

Have a true false field when accomplished.

So Joe is logging in, field is false, that tells you to create new hashed password.

Next time Joe logs in, true, so check new hash.

Backup data before implementing anything.

Will take a little coding to accomplish. Practice first on test data.

I’m no expert on these details, but what you have generally looks okay. I’d put a breakpoint in the check function to see what the incoming data looks like, and where it came from.

Update.
the user password field was blob, I changed to varchar, now everything works