I have an issue using crypt() where if a user has a password (password1 in this example), and they change it to password2, the hashing returns the same result. You can test that here: OLD LINK Type password1 as current password, and password2 as new password and confirm password, you will see the results. If a completely non similar password is entered there is no problem. I understand there are other ways to go about hashing passwords etc. I'm more curious than anything. My code is below:
<?php
$oldpassword="password1";
echo "<form method=\"post\">
<p>Enter Current Password: <input type=\"password\" name=\"currentpassword\" /></p>
<p>Enter New Password: <input type=\"password\" name=\"password\" /></p>
<p>Confirm New Password: <input type=\"password\" name=\"confirmpassword\" /></p>
<p><input type=\"submit\" value=\"Change Password\"></p>
</form>";
$user_id = $_SESSION['user_id'];
$pass=$_POST['password'];
$salt = 'xxxxx';
$currentpassword = crypt($_POST['currentpassword'], $salt);
$oldpassword = crypt($oldpassword, $salt);
if(isset($_POST['password'])) {
if ($currentpassword !== $oldpassword) {
echo "The password you entered for current password does not match our records.";
}
else {
if ($_POST['password'] && $_POST['confirmpassword']) {
if ($_POST['password'] == $_POST['confirmpassword']) {
$hash = crypt($pass, $salt);
if ($hash == $currentpassword) {
echo "Current Password: ";
var_dump($_POST['currentpassword']);
echo "<br/>";
echo "New Password: ";
var_dump($_POST['password']);
echo "<br/>";
echo "New Hash: ";
var_dump($hash);
echo "<br/>";
echo "Current Password Hash: ";
var_dump($currentpassword);
echo "<br/>";
echo "<hr/>";
echo "Your new password cannot be the same as your current password.";
}
else {
echo "Your password has been changed successfully<br/>";
}
} else {
echo "Your passwords do not match. Please try again.";
}
}
}
}
?>
When hashing passwords, two passwords can produce the same hash, so if a user inputs someone else's username but his own password, there is a possibility that he will be able to login to that other account.
password_hash() creates a new password hash using a strong one-way hashing algorithm. The following algorithms are currently supported: PASSWORD_DEFAULT - Use the bcrypt algorithm (default as of PHP 5.5. 0). Note that this constant is designed to change over time as new and stronger algorithms are added to PHP.
Bcrypt cost Bcrypt is the current default hashing algorithm used by password_hash(). This algorithm takes an option parameter named “cost”. The default cost value is 10.
To use crypt you have to provide proper salt. Every algorithm has its own salt format. My guess is that you are using few random chars as salt, this does no match any advanced algo, so php cuts down your salt to first 2 character and fallbacks to basic DES
algorithm. DES
algorithm hashes up to 8 characters and both password1
and password2
are 9 character long, so only password
is used from both, hence same hash.
Solution: use proper salt format for strongest available algorithm, generate random salt for each password
Recommended solution: https://github.com/ircmaxell/password_compat (for php 5.3.7 - 5.4.x) and after switching to php 5.5: http://php.net/password_hash
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With