Hello everyone!

We have been investing plenty of personal time and energy for many years to share our knowledge with you all. However, we now need your help to keep this blog running. All you have to do is just click one of the adverts on the site, otherwise it will sadly be taken down due to hosting etc. costs. Thank you.

As of writing this post, hashing passwords with Argon2 algorithm is recommended by IETF. In this example we are going to use Sodium to hash and verify passwords with Argon2id in our PHP 7.2 application.


Class


You might need to add "ext-sodium": "*" to your composer.json file.


class PasswordHasher
{
public function hash(string $plainPassword): string
{
return sodium_crypto_pwhash_str(
$plainPassword,
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
}

public function verify(string $plainPassword, string $hashedPassword): bool
{
$result = sodium_crypto_pwhash_str_verify($hashedPassword, $plainPassword);

sodium_memzero($plainPassword);

return $result;
}
}

Test


class PasswordHasherTest extends TestCase
{
public function testHash(): void
{
$hash = (new PasswordHasher())->hash('inanzzzinanzzz');

$this->assertStringStartsWith('$argon2id$v=19$m=65536,t=2,p=', $hash);
$this->assertSame(97, \strlen($hash));
}

/**
* @dataProvider passwordDataProvider
*/
public function testVerify(string $plainPassword, string $hashedPassword, bool $result): void
{
$this->assertSame($result, (new PasswordHasher())->verify($plainPassword, $hashedPassword));
}

public function passwordDataProvider(): array
{
return [
'Test with invalid password but valid hash' => [
'$plainPassword' => 'invalid_password',
'$hashedPassword' => '$argon2id$v=19$m=65536,t=2,p=1$Lum8Qyd9RS+q5wlDYHfACA$1YUvs5HNdq7MVY0YAVV7SxyrSp309CfyS3BUFfuR+GE',
'$result' => false,
],
'Test with valid password but invalid hash' => [
'$password' => 'inanzzzinanzzz',
'$hashedPassword' => 'invalid_hash',
'$result' => false,
],
'Test with valid password and hash' => [
'$password' => 'inanzzzinanzzz',
'$hashedPassword' => '$argon2id$v=19$m=65536,t=2,p=1$Lum8Qyd9RS+q5wlDYHfACA$1YUvs5HNdq7MVY0YAVV7SxyrSp309CfyS3BUFfuR+GE',
'$result' => true,
],
];
}
}