繁体   English   中英

每个字符串的PHP password_hash函数值都不相同

[英]PHP password_hash function value isn't same for each string

我尝试使用password_hash() PHP函数来哈希用户密码。但是,它的功能是工作哈希,而不是常量。

<?php 
    echo password_hash('a',PASSWORD_BCRYPT,array(
            'cost' => 12
         ));
?>

第4次测试时间的结果

1. $2y$12$SRmipqM7AsYkx3Xc8QGHNex69rGXeVyWGTYrh9T8sh1cP3UrdjfQi
2. $2y$12$zx.GUgtcake3wMfl3/YXXeG1.8mmHKyRruL3nWj8OmA.RbEYqeW6u
3. $2y$12$XQtmFplcehkgWLbGrOUsNOlXDU/NGrwZlt3HM88hLbUHXhjXNF4km
4. $2y$12$q9/OSZdDJw7af4Hw4MGlHeY7UMtWr9/Cj0nj/N6PaoilNoUBePt7O

有些人建议使用MD5,不要用它来进行密码散列。

那么现在回答你的问题how to check a password matches

Password_Hash()是生成一个密码哈希,它会随之创建一个随机盐,这个哈希将在哈希时使用。 你的最终结果将是:salt + hash, 但是你可以在它的选项中用这个方法给它一个salt但是让它保持它自己做它。

Password_Verify()使用密码参数和散列密码。 正如我之前所说的,散列密码是salt + hash,这是有道理的, Password_Verify()只需要这些,而不是另外一个叫做salt

所以Password_Verify()会发生什么,它取出盐并使用该盐的Password_Hash() 然后检查接收的散列是否等于给定的散列。 如果它匹配那么它是真的,否则它是假的。

Password_Hash()文件

Password_Verify()Doc


更新18-04-2018(dmY)

警告

PHP 7.0.0起 ,salt选项已被弃用

现在优选简单地使用默认生成的盐。

有关Salting的更多信息 - SO回答以下Veve

为什么不使用MD5进行密码散列 - PHP FaQ答案

为什么不使用MD5进行密码散列 - 请回答:Silverlightfox

如果你想使用password_hash()并获得常量哈希(不确定复数...),请在使用时添加一个盐 (但请不要,请参阅下面的注意事项

正如文档中解释的那样 ,如果不这样做,每次使用函数时都会随机生成salt,因此生成的哈希值不会是常量。

<?php 
    echo password_hash('a',PASSWORD_BCRYPT,array(
            'salt' => $salt_defined_for_the_user,
            'cost' => 12,
         ));
?>

关于你应该使用的盐,这里是从这里提取的wmfrancia的一个很好的解释:

在散列之前,密码应该总是被腌制。 Salting会在密码中添加一个随机字符串,因此类似的密码在数据库中看起来并不相同。 但是,如果盐不是每个用户独有的(即:你使用硬编码的盐),那么你的盐几乎没有价值。 因为一旦攻击者找到一个密码盐,他就会为所有人提供盐。

创建salt时,请确保它对于密码是唯一的,然后将完成的散列和salt存储在数据库中。 这样做是为了让攻击者在获得访问权限之前必须单独破解每个盐和哈希值。 这意味着攻击者需要做更多的工作和时间。


注意:你不应该试着用你自己的盐来获得常数哈希值

我只是在这里回答你愿意有恒定的哈希值,但由上述halfermartinstoeckli中的意见,并在官方文档还指出,

注意强烈建议您不要为此功能生成自己的盐。 如果您没有指定,它将自动为您创建安全盐。

你真的应该创建自己的盐,功能会尽可能创造一个安全和随机一个。 如示例所示,当您存储特定于用户的salt时,无论如何都会执行与password_hash()相同的操作。 它包含哈希值中的salt,因此函数password_verify()可以从那里获取它

Mike M. 在他的回答中有一个使用password_verify()的详细描述。

无论您尝试多少次,我认为您会对生成相同哈希的旧方法感到困惑。

例如,MD5()会一直为同一个密码提供相同的哈希值。

Password_hash始终为您提供不同的字符串,因为它每次运行时都包含不同的盐。

当您从数据库中检索哈希密码时(例如,基于用户提供的电子邮件),Password_verify将读取整个字符串,即盐+传递在一起,将使用第一个字符,即盐,并将使用此盐与平原用户提供加密密码。

然后它会将结果与从数据库中提取的剩余salt + hash进行比较(剩下的现在应该是哈希值而不是盐)。

我希望这有助于理解为什么tou会一直使用密码哈希来获取相同的密码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM