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

Php 使用crypt()时在数据库中生成和存储盐,php,mysql,cryptography,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"]==sh

我过去常做的事:

$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()
是垃圾,所以我决定使用。我没有使用和,因为有时我必须将站点移动到另一台具有不同(有时更旧)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
    是否总是正确的?(现在我意识到我可以从这个问题开始)

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

  • 我意识到我可以测试其中的大部分,但在安全性方面,我宁愿有专家的意见

  • 不,它可能因服务器而异;这取决于可用的算法
    password\u hash
    允许您指定算法

  • 见1
    password\u hash
    crypt
    兼容


  • 您的代码还有一个问题:


    你的盐代不够随机<代码>兰德不是很好
    mt\u rand
    稍好一些,
    openssl\u random\u pseudo\u bytes
    很好,建议使用
    password\u hash

    好的,但是当我不得不将一个在PHP 5.5+上的站点移动到一个在早期PHP版本上的服务器时,该怎么办?用户还能登录吗?这取决于
    crypt
    是否决定使用相同的算法。如果您要升级到支持
    密码\u哈希
    的服务器,则可以将旧密码转换为新选择的算法。但是降级是不可能的。是的,我还是要使用密码_hash()。我第一次读到它在PHP<5.3.7上不起作用,但它在我尝试过的每台托管服务器上都能起作用(甚至在5.2.17上),这真的很方便。希望它没有任何漏洞。请使用mt_rand。Rand和mt_Rand都是伪随机的,如果您希望完全验证salt生成器包含random.org中的整数。它使用大气噪声。您可以使用cURL收集数字。因此,要破解一个用户的密码,攻击者必须知道密码被哈希的确切时间,猜测两个随机生成的数字,反转md5哈希,然后反转crypt()所做的任何操作,这仍然是不安全的?你可能会认为攻击者会直接到用户家中敲出他的密码。哦,是的,是的