在PHP应用程序中使用Sodium来散列密码的实例

106 阅读1分钟

在写这篇文章时,IETF推荐使用Argon2算法对密码进行散列。在这个例子中,我们将在我们的PHP7.2应用程序中使用Sodium来散列和验证密码,Argon2id

你可能需要在你的composer.json 文件中添加"ext-sodium": "*"

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;
    }
}
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,
            ],
        ];
    }
}