【发布时间】:2014-04-24 22:50:43
【问题描述】:
我曾经做过的事情:
$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()时,我真的不需要将盐存放在任何地方吗?crypt($something,$somethingelse)==$somethingelse在 $something==$somethingelse 时总是正确的吗? (现在我意识到我可以从这个问题开始)在较新的 PHP 版本上使用 compatibility pack 生成的哈希值可能与在较旧的 PHP 版本上生成的哈希值不同,因此实际上使生成的密码在不同版本的 PHP 之间不兼容,我说得对吗?如果是这样,为什么它被称为“兼容性”包?
我知道我可以测试其中的大部分内容,但在安全性方面我宁愿听取专家意见。
【问题讨论】:
-
使用 mt_rand。 Rand 和 mt_rand 都是伪随机的,如果你想要完整的证明盐生成器包括来自 random.org 的整数。它使用大气噪声。您可以使用 cURL 来收集数字。
-
因此,要破解一个用户的密码,攻击者必须知道密码被散列的确切秒数,猜测两个随机生成的数字,反转 md5 散列,然后反转 crypt() 所做的任何事情,然后这仍然不安全吗?你会认为攻击者只是去用户家并从他那里破解密码。哦,好吧,mt_rand() 它是。 :)
标签: php mysql cryptography