php - 使用 crypt() 时在数据库中生成和存储盐

标签 php mysql cryptography

我曾经做过的事情:

$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;

所以我的问题是:

  1. 使用 crypt() 时,我真的不需要在任何地方存储盐吗?当 $something==$somethingelse 时,crypt($something,$somethingelse)==$somethingelse 是否始终为真? (现在我意识到我可以从这个问题开始)

  2. compatibility pack 生成的哈希值对吗?在较新的 PHP 版本上生成的密码可能与在较旧的 PHP 版本上生成的密码不同,因此实际上使生成的密码在不同版本的 PHP 之间不兼容?如果是这样,为什么它被称为“兼容”包?

我知道我可以测试其中的大部分内容,但在安全性方面我更愿意听取专家意见。

最佳答案

  1. 不,它可能因服务器而异;这取决于可用的算法。 password_hash 允许您指定算法。

  2. 参见 1. password_hashcrypt 兼容。


您的代码还有一个问题:

您的盐生成不够随机。 rand 不是很好。 mt_rand 稍微好一些,openssl_random_pseudo_bytes 不错,推荐password_hash(但你知道这个)。

关于php - 使用 crypt() 时在数据库中生成和存储盐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23281268/

相关文章:

php - 何时在 Laravel 5.x 中编写存储过程

java - 加密和解密最终 block 未正确填充错误?

java - Rijndael C# 和 Java 之间的差异

php - Symfony 4的Rest-bundle需要4.3版本的配置,而Symfony 4使用5.0版本

php - 从 url 中获取元描述、标题和图像,如 facebook 链接共享

php - 转换表列后无法获取数据

sql - 如何优化 MySQL 查询?

Android Dev : Run custom code in the Trusted Execution Environment (TEE), 扩展 keystore

php - 如何从 ubuntu 运行 PHP 文件?

JQuery-UI Slider - 将数值存储到 MySQL 但向用户显示字符串值