香港专业教育学院一直在阅读关于php 5.3+ password_hash的内容 - 但是有一些问题,请原谅我,如果我是愚蠢的.看起来制作强大的用户密码哈希的一个重要问题是使用随机盐而不是静态盐.如果我正在检查登录的用户,我肯定要以某种方式获得使用的盐的副本(存储在db中)来检查?如果是这种情况,我是否使用安全盐函数(bcrypt salt函数)并将该字符串存储在db中(并在每次新登录时重新创建)或者是什么?
我有这个:
$options = [ 'cost' => 11, 'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
].
当我回显$ options ['salt']时,我得到奇怪的字符,我无法存储在数据库中.我习惯于在db中存储随机盐的旧(不安全)方法,并使用(静态)用户登录auth,但动态/随机盐让我失望了.我错过了什么?随机盐每次都会更改,所以如果我现在存储它,并且重新登录哈希的用户会有所不同,所以db密码与发布的密码不匹配.
谢谢〜
看起来制作强大的用户密码哈希的一个重要问题是使用随机盐而不是静态盐.
随机盐是PHP 5.5 password_hash()
和用户态实现password_compat的默认行为.
如果我正在检查登录的用户,我肯定要以某种方式获得使用的盐的副本(存储在db中)来检查?
salt包含在密码哈希本身中.无需单独存储.
随机盐每次都会更改,所以如果我现在存储它,并且重新登录哈希的用户会有所不同,所以db密码与发布的密码不匹配.
这是该password_verify()
方法的责任.从PHP文档:
请注意,password_hash()返回算法,cost和salt作为返回哈希的一部分.因此,验证哈希所需的所有信息都包含在其中.这允许验证功能验证散列,而无需为盐或算法信息单独存储.
编辑:密码验证和随机盐
我想我明白你的困惑来自哪里.希望这有助于解释密码散列,验证和随机盐播放的部分.
如果你看一下password_compat的源代码(https://github.com/ircmaxell/password_compat/blob/master/lib/password.php),你会看到两者password_hash()
并password_verify()
利用PHP的crypt()
功能.使用时创建密码password_hash()
,您将其存储,并且永远不会password_hash()
再次传递该密码.算法,成本和盐都是用哈希返回的.例:
$options = array('salt' => 'ThisIsTheSaltIProvide.'); $hash = password_hash('password', PASSWORD_DEFAULT, $options); // $hash = $2y$10$ThisIsTheSaltIProvide.EcCQwybvWB3iNxIv9FwsPJEWhR/ywZ6
我们可以通过直接使用crypt创建相同的哈希,这正是password_hash()
幕后的原因.
$hash = crypt('password', '$2y$10$ThisIsTheSaltIProvide.'); // $hash = $2y$10$ThisIsTheSaltIProvide.EcCQwybvWB3iNxIv9FwsPJEWhR/ywZ6
哈希包括:
Algo信息:$ 2y $(BLOWFISH)
成本参数:10
额外的$
盐:ThisThesTheSaltIProvide.
使用该信息,password_verify()
再现哈希,然后将其与持久化哈希进行比较,如下所示:
$existingHash = $2y$10$ThisIsTheSaltIProvide.EcCQwybvWB3iNxIv9FwsPJEWhR/ywZ6 $testHash = crypt('password', '$2y$10$ThisIsTheSaltIProvide.'); // if $existingHash and $testHash match, then the password is good
一种新的,额外的盐永远不会发挥作用.
此外,使用RANDOM盐很重要.如果每个人都使用相同的salt,那么具有相同密码的用户也将具有相同的哈希值.没有人想要那样.