Long story short, I’ve got some passwords that were improperly salted and hashed in a version of PHP that allowed the crypt() function to fall back to the CRYPT_STD_DES algorithm if the salt was invalid.
However in PHP 5.3.2+:
5.3.2 Fixed Blowfish behaviour on invalid rounds to return “failure” string (“*0” or “*1”), instead of falling back to DES.
What makes this a problem is that the salt contained the “$” character as it was intended to be a blowfish salt (but was unknowingly malformed).
Thus I am unable to manually do something like the following:
crypt($pass, "$a");
since that is not a valid CRYPT_STD_DES salt either now. The salt must be in the range “./0-9A-Za-z”. It simply returns “*0” as the PHP devs intended.
How can I validate these malformed passwords in a more recent version of PHP (at least 7.1, ideally)?
3
Answers
As a workaround, I ended up actually using the old version of PHP for a single directory where I could make a
file_get_contents()
call and retrieve a hash with the old (bugged) algorithm, but still use the more modern version of PHP elsewhere.This is not a proper solution, however, as it technically does not answer the question: "How can I validate these malformed passwords in a more recent version of PHP?"
As such, unless there appears to be no other possible solution, I will not be marking this as the accepted answer (but I believe this answer should be added for completeness sake).
you are probably looking for
https://www.php.net/manual/en/function.password-hash.php
Found an actual solution. By bruteforcing the salts, it turns out that PHP was interpreting the invalid "$2" STD_DES salt as "q2".
Therefore, the answer to this question is that one can validate these hashes in a newer version of PHP by altering the salt used to compare the hashes so that it begins with "q2" instead of "$2". From there, it’s possible to just call
substr_replace($str, '$', 0, 1);
to replace the newly added "q" character back to a "$" character when performing the equality check.As an anecdote, apparently the information I had was incorrect and the hashes were generated in PHP 5.3.29 which contradicts what the docs say about falling back to STD_DES being patched in version 5.3.2.