Why is the PHP crypt() function returning the same thing for two different strings?

大兔子大兔子 提交于 2019-12-03 18:12:01

问题


I'm using PHP's crypt function for password hashing/encryption, but I don't think I am doing it right because "nathan12" and "nathan123" both allow me to login to my account on my system (the actual password is "nathan123", and therefore "nathan12" or anything else should NOT allow me to login).

Here's what my system does when a user registers:

[...]

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

[...]

It inserts the hashed/encrypted password ($password) into the database along with the $salt.

When someone tries to login, the following is done to check if the user has inputted the correct password for the username they inputted:

[...]

// $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) { 

[...]

I'm probably not even using the crypt function properly, but according to the PHP docs the first parameter is a string (the password) and second is the salt.


回答1:


The standard DES-based crypt() [...] only uses the first eight characters of str, so longer strings that start with the same eight characters will generate the same result (when the same salt is used).

source

Use a salt that starts with $<algo>$ to use something other than DES. See the crypt() documentation for details.




回答2:


You should be using password_hash() instead of crypt, for the reasons you mention: "I'm probably not even using the crypt function properly". You say you are getting the salt from the DB... this sounds insecure. with password_hash() you can let PHP handle the salting for you in a secure manner.

More details on why this is superior: http://www.sitepoint.com/hashing-passwords-php-5-5-password-hashing-api/




回答3:


You should use more than just a password salt to encrypt passwords.

You can store a random string in your configuration file.

$config['passwordKey'] = 'asjdfa783#H$Khjsdfhas78a734J%JSDGK2348235hxmfdA';

And append it to $salt when encrypting. This way if the database is compromised, and your file system is not, then attackers can't decrypt your database password hashes. This should be essential to protect the users information on other sites with identical login information.


To hash your passwords, password_hash is a simple crypt() wrapper specially configured for password hashing! (source)

$password = password_hash($password, PASSWORD_BCRYPT, array(
    'cost' => 60,
    'salt' => $salt . $config['passwordKey']
));


来源:https://stackoverflow.com/questions/20875703/why-is-the-php-crypt-function-returning-the-same-thing-for-two-different-strin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!