为什么PHP crypt()函数为两个不同的字符串返回相同的内容?
我使用PHP的为什么PHP crypt()函数为两个不同的字符串返回相同的内容?,php,mysql,password-protection,Php,Mysql,Password Protection,我使用PHP的crypt函数进行密码散列/加密,但我认为我做得不对,因为“nathan12”和“nathan123”都允许我登录到我系统上的帐户(实际密码是“nathan123”,因此“nathan12”或其他任何东西都不允许我登录) 以下是我的系统在用户注册时所做的操作: [...] $salt = uniqid(mt_rand(), true); $password = crypt($password, $salt); // '$password' is the inputted pass
crypt
函数进行密码散列/加密,但我认为我做得不对,因为“nathan12”和“nathan123”都允许我登录到我系统上的帐户(实际密码是“nathan123”,因此“nathan12”或其他任何东西都不允许我登录)
以下是我的系统在用户注册时所做的操作:
[...]
$salt = uniqid(mt_rand(), true);
$password = crypt($password, $salt); // '$password' is the inputted password
$insertUserStmt = $mysqli->prepare("INSERT INTO users (name,
username,
password,
password_salt,
email,
created) VALUES (?, ?, ?, ?, ?, ?)");
$insertUserStmt->bind_param("sssssi", $name, $username, $password, $salt, $email, time());
$insertUserStmt->execute();
[...]
它将哈希/加密密码($password
)与$salt
一起插入数据库
当有人尝试登录时,将执行以下操作以检查用户是否为其输入的用户名输入了正确的密码:
[...]
// $password_salt is from DB; $password is inputted password
$password_crypt = crypt($password, $password_salt);
// $login_password is from DB
if($password_crypt == $login_password) {
[...]
我甚至可能没有正确使用crypt
函数,但根据PHP文档,第一个参数是字符串(密码),第二个是salt。您应该使用crypt而不是crypt,因为您提到的原因:“我甚至可能没有正确使用crypt函数”。你说你从DB那里得到盐。。。这听起来不安全。使用password_hash()可以让PHP以安全的方式为您处理盐渍
有关这一优势的更多详细信息:
基于DES的标准crypt()
[…]仅使用str
的前八个字符,因此以相同八个字符开头的较长字符串将生成相同的结果(使用相同的salt时)
使用以
$$
开头的盐来使用DES以外的其他东西。有关详细信息,请参阅crypt()
文档。您应该使用密码盐来加密密码
您可以在配置文件中存储随机字符串
$config['passwordKey'] = 'asjdfa783#H$Khjsdfhas78a734J%JSDGK2348235hxmfdA';
并在加密时将其附加到$salt
。这样,如果数据库被破坏,而您的文件系统没有被破坏,那么攻击者就无法解密您的数据库密码哈希。这对于保护具有相同登录信息的其他站点上的用户信息至关重要
要散列密码,
password\u hash
是一个简单的crypt()
包装器,专门为密码散列配置!
()
您是否检查过数据库中是否存储了不同的哈希值?如果没有更多的信息,就很难确定这个问题。(另请注意:如果您使用的是PHP5.5+,那么您真的应该使用它。)@Amber是的,我检查了我的数据库,所有用户的哈希都不同(目前只有两个用户-我和一个测试帐户)。但是我不认为这对一个用户来说会有什么不同,因为密码是相同的,它不允许我输入两种不同的东西。从数据库获取salt并不是天生的不安全。这也是
password\u hash
应该做的事情;它只是碰巧将salt存储在与密码相同的字符串中,而不是存储在单独的字段中。@Amber correct。并非天生不安全,但正如他提到的,他不太确定自己在做什么,我有一种感觉,他很可能正在存储一种盐,并为所有用户使用它。@DigitalChris在我的设置中,每个用户都有自己的盐(我甚至检查了我的数据库)。但是我会使用密码散列来代替,并尝试其他回答者的建议。我尝试在salt前面加上$(如下),它对“nathan 123”有效,但对于“nathan”,它返回“$”,对于“nathan 12”,它返回与“nathan 123”相同的东西,因此crypt
似乎一点也不可靠<密码>密码($password,“$$”$password\u salt.password\u KEY)
常量password\u KEY
是Sam答案中的密钥。@Nathan:你选择了哪种算法?好的,我在salt(这是sha-256
算法)前面加了$5$
,看起来它现在正在工作。我尝试了“nathan”、“nathan1”等,它为所有这些文件生成了不同的加密。非常感谢。
$password = password_hash($password, PASSWORD_BCRYPT, array(
'cost' => 60,
'salt' => $salt . $config['passwordKey']
));