我曾经做过的事情:
$salt = md5(time().rand(0,9999999).rand(0,100000));
$hashed_password = sha1($salt.$_REQUEST["newpassword"].sha1($salt));
$query = "update users set password=:hashed_password, salt=:salt where uid=:uid";
然后检查密码
if ($mysql_row["password"]==sha1($mysql_row["salt"].$_REQUEST["loginpassword"].sha1($mysql_row["salt"]))) loginsuccess = true;
现在我发现这是一种不安全的密码存储方式,因为 sha1()
是垃圾,所以我决定使用 crypt() .我没有使用 password_hash()和 compatibility pack因为我有时不得不将站点移动到另一台具有不同(有时是旧的)PHP 的服务器,并且我希望在更高版本的 PHP 上生成的哈希/密码仍然可以在具有早期 PHP 版本的服务器上运行。
所以 crypt()
说我可以做类似的事情
$salt = md5(time().rand(0,9999999).rand(0,100000));
$hashed_password = crypt($_REQUEST["newpassword"],$salt);
$query = "update users set password:hashed_password where uid=:uid"; // doesn't save salt
然后检查密码:
if (crypt($_REQUEST["loginpassword"], $mysql_row["password"]) == $mysql_row["password"]) $loginsuccess = true;
所以我的问题是:
使用
crypt()
时,我真的不需要在任何地方存储盐吗?当 $something==$somethingelse 时,crypt($something,$somethingelse)==$somethingelse
是否始终为真? (现在我意识到我可以从这个问题开始)用 compatibility pack 生成的哈希值对吗?在较新的 PHP 版本上生成的密码可能与在较旧的 PHP 版本上生成的密码不同,因此实际上使生成的密码在不同版本的 PHP 之间不兼容?如果是这样,为什么它被称为“兼容”包?
我知道我可以测试其中的大部分内容,但在安全性方面我更愿意听取专家意见。
最佳答案
不,它可能因服务器而异;这取决于可用的算法。
password_hash
允许您指定算法。参见 1.
password_hash
与crypt
兼容。
您的代码还有一个问题:
您的盐生成不够随机。 rand
不是很好。 mt_rand
稍微好一些,openssl_random_pseudo_bytes
不错,推荐password_hash
(但你知道这个)。
关于php - 使用 crypt() 时在数据库中生成和存储盐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23281268/