PHP密码\u散列函数值为&\x27;每个字符串不相同

PHP密码\u散列函数值为&\x27;每个字符串不相同,php,password-hash,php-password-hash,Php,Password Hash,Php Password Hash,我尝试使用password\u hash()PHP函数散列用户密码。但是,它的函数是工作散列,不是常量 <?php echo password_hash('a',PASSWORD_BCRYPT,array( 'cost' => 12 )); ?> <?php echo password_hash('a',PASSWORD_BCRYPT,array( 'salt' => $salt

我尝试使用password\u hash()PHP函数散列用户密码。但是,它的函数是工作散列,不是常量

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

如果要使用
password\u hash()
并获取常量哈希(不确定复数…),请在使用时添加一个salt。(但不要这样做,请参见下面的注意事项)

同样,如果不这样做,每次使用该函数时,salt都会随机生成,因此生成的哈希值不会是常量

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

关于你应该使用的盐,下面是一个很好的解释:

腌制

密码在散列之前应始终进行腌制。加盐会增加一个随机的结果 字符串设置为密码,这样类似的密码在 DB。但是,如果盐不是每个用户独有的(即:您使用 硬编码的盐)比你几乎使你的盐一文不值。 因为一旦攻击者找出一个密码,他就有了密码 为了他们所有人

创建salt时,请确保其密码是唯一的 salt,然后将完成的哈希和salt存储在数据库中。什么 这样做的目的是使攻击者必须单独 在他们进入之前,先把每一块盐都打碎,然后再把它们散开。这意味着很多 攻击者需要更多的工作和时间


注意:你不应该尝试用你自己的盐来获取常量散列 我在这里只是回应你愿意不断地进行散列,但正如和在评论中所说的,以及在官方文件中所指出的

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

你真的不应该自己创造盐,函数尝试它 最好创建一个安全和随机的。当您存储用户特定的 salt正如您的示例所示,您的操作与password_hash()相同 无论如何它在散列值中包含salt,因此函数 密码\u verify()可以从那里获取它


有关于的详细说明。

一些人建议使用MD5,不要将其用于密码哈希

现在回答您的问题
如何检查密码匹配

Password\u Hash()
是生成一个密码散列,它将创建一个随机的salt,这个散列将在散列时使用。 您的最终结果将是:salt+hash,但是您可以在它的选项中使用此方法为它指定一个
salt
,但让我们保持它是由它自己完成的

Password\u Verify()
为密码使用一个参数,为散列密码使用一个参数。 正如我前面所说的,散列密码是salt+hash 这说明
Password\u Verify()
只需要这些,而不需要额外的
salt

因此,使用
Password\u Verify()
时,它会取出salt并使用
Password\u Hash()
。 然后检查收到的散列是否等于给定的散列。 如果匹配,则为真,否则为假


更新2018年4月18日(d-m-Y)

警告

自PHP 7.0.0以来,salt选项已被弃用

现在更倾向于使用默认生成的盐


我想你会被那些老方法弄糊涂,不管你尝试多少次,它们都会产生相同的哈希值

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

密码\u哈希始终为您提供不同的字符串,因为每次运行它时它都包含不同的盐

从数据库检索哈希密码时(例如,基于用户提供的电子邮件) Password_verify将读取整个字符串,即salt+pass,将使用salt的第一个字符,并将此salt与用户提供的用于加密的普通密码一起使用

然后将结果与从数据库中提取的salt+散列的剩余部分进行比较(剩余部分现在应该是没有salt的散列)


我希望这有助于您理解为什么每次使用相同密码的密码哈希时都会得到不同的字符串。

您希望得到什么?它会是常量吗?每次使用
密码\u hash()
而不使用salt时,它会生成一个随机salt,这意味着密码不会是常量。由于
password\u hash()
生成散列,散列基本上是salt+hash
password\u verify()
方法需要密码和散列密码,密码[param 1]将使用散列密码中的salt进行散列,如果它等于,则返回true,否则失败:-)没问题,请记住,如果这有帮助的话,别忘了接受答案:-)我还想说:只使用给出的方法。生成的salt非常好,使用
password\u hash()
password\u verify()
我真的理解
password\u hash()
password\u verify()。谢谢你@MikeM。我太晚了,无法接受您的答案。$salt_defined__用户只需至少22个字符:P:)除非您知道自己在做什么,否则我建议使用此函数的默认salt功能。您确实不应该创建自己的salt,该函数会尽最大努力创建一个安全且随机的salt。如示例所示,当您存储用户特定的salt时,您执行的操作与
密码\u hash()
执行的操作相同。它在散列值中包含salt,因此函数
password\u verify()
可以从中提取它。我不是说他必须创建salt,我只是回答他关于获取常量散列的问题。我会在我的答案中加上你的警告。我已经检查了我的答案。我已经详细解释了,没有了