PHP crypt() returns *0 failure string in version 5.6.4, but not 5.4,
Asked Answered
G

1

6

echo crypt('test', "$2a$07$"); produces a long hash in PHP version 5.4.16, but it produces the "failure string" *0 in 5.6.4.

Reading the PHP docs on crypt(), I'm still not quite clear why, though the Changelog mentions the *1 being returned instead of *0 depending on the circumstance. (http://php.net/manual/en/function.crypt.php)

What is the reasoning for *0 being returned in this case? Did PHP past 5.4 stop tolerating the bad salt of the form $2a$07$?

Gimmick answered 22/1, 2015 at 21:42 Comment(1)
Congrats for the PHP developers for writing such an utter crap. Returning some random string in a security function instead of returning false or throwing an exception as every sane person would assume is just unacceptable. If I could choose language I would never ever choose PHP. If I wouldn't test my classes I would have never noticed this massive vulnerability I added to the code by using this function. Even in this case some of my tests just randomly failed for base64 encoded salt, because they contained / and +. So this crypt function is netiher binary nor base64 compatible.Vries
D
10

The Blowfish definition says that you have to define a string after the third $.

<?php
echo crypt('test',  "$2a$07$mystring");
?>

Blowfish hashing with a salt as follows: "$2a$", "$2x$" or "$2y$", a two digit cost parameter, "$", and 22 characters from the alphabet "./0-9A-Za-z"

When you don't define that string you get an error *0.

5.6.5 When the failure string "*0" is given as the salt, "*1" will now be returned for consistency with other crypt implementations. Prior to this version, PHP 5.6 would incorrectly return a DES hash.

Dripdry answered 22/1, 2015 at 22:39 Comment(1)
I read that like ten times (and even linked to it in my question) but for some reason it didn't stick. Duh. Thanks.Gimmick

© 2022 - 2024 — McMap. All rights reserved.