I am running into some issues with my log in system. If I set my user password to 'TestPassword1234', 'TestPassword' will be accepted as the password.
After testing some more I found out that the following code will result in two identical hashes being created even though the string passed is not the same.
It is important to know that all salts used are generated by this function. One is generated per test and the same one is used to hash both strings (just like it would be when logging a user in).
function GUID() {
if (function_exists('com_create_guid') === true) { return trim(com_create_guid(), '{}'); }
return sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535));
}
The above function was sourced from a stack overflow question, I am not sure which.
This is not the case if the password is fundamentally changed, see below for tests.
The following snippet shows two different passwords resulting in the same hash.
$guid = GUID();
echo( crypt("TestPassword1234", $guid ) ); //455nKS7NToPuY
echo("<br />");
echo( crypt("TestPassword", $guid ) ); //455nKS7NToPuY (the same!)
This snippet shows two different passwords not resulting in the same result even though they follow a similar pattern to the above snippet
$guid = GUID();
echo( crypt("Test1234", $guid ) ); //BBWxwWzIXAOQI
echo("<br />");
echo( crypt("Test", $guid ) ); //BBhe4TjDcO5XA (different...)
I assume the problem originates from the use of the GUID function. Perhaps it is faulty or only supports a password with a max length of x
. I have no idea and cannot track down the SO question I found it on.
Help is much appreciated.
To use crypt() you must comply to one of the algorithm salt formats listed in the manual. You are not following one of the formats and as such PHP is reducing your salt down to the first two characters, and calculating it using the DES algorithm. DES only uses the first 8 characters and as such you are only hashing "TestPass" with the same salt twice.
The better thing to do is use password_hash() instead. However, as you mentioned your host does not support password_hash().
If crypt() is the final choice then you will require to format a salt correctly. However, the best of algorithms to chose from with crypt() only allows a max of 16 characters for the salt. As such using a GUID is not the best choice due to most of the data going un-used.
Here is an example using a secure random byte generator, This will only work on PHP 5.3.2 and beyond:
function newSalt() {
$salt = bin2hex(openssl_random_pseudo_bytes (8));
return '$5$'.$salt;
}
$salt1 = newSalt();
$salt2 = newSalt();
echo( crypt("TestPassword1234", $salt1 ) );
echo("<br />");
echo( crypt("TestPassword", $salt2 ) );
You can store the salt for later using by storing the values generated from newSalt()
Edit: OP's PHP installation is too old for any decent implementations. I highly suggest finding a server that supports a higher version. I hope that my example helped you or someone else, as well as the reasoning due to the original password similarities.