1

PHP crypt function is said to have this return value:

"Returns the hashed string or a string that is shorter than 13 characters and is 
guaranteed to differ from the salt on failure."

I don't understand what this means... I've understood basically how this function works but I would like to know how to interpret the return value and try to understand WHEN this condition occurs.. this is by far one of the vaguer explanations in the PHP manual or maybe I'm just blind from starring at it for too long...? :)

fast-reflexes
  • 4,891
  • 4
  • 31
  • 44
  • Dunno how much it matters, but `crypt` can of course fail when you call it wrong -- ie: when `$str` (or `$salt`, if provided) can not be legitimately turned into a string. For example, if you pass an array, a resource, or an instance of a class that doesn't define a `__toString()` function. On my machine, though, this causes `crypt` to return `null`, rather than a string. – cHao May 25 '13 at 00:34
  • gotcha... well even though it may pass a short string as a sign of failure.. I'm interested in finding out why they make a point of saying that it differs from the salt on failure... – fast-reflexes May 25 '13 at 11:06

1 Answers1

2

The one thing the crypt documentation mentions:

(5.3.2) Fixed Blowfish behaviour on invalid rounds to return "failure" string ("*0" or "*1"), instead of falling back to DES.

Apparently crypt can return different [poorly-specified] short strings on failure. I suspect the "or" bit is to account for "differ from the salt".

In this manner, a string "shorter than 13 characters" (of who knows what) -> failure. The only documented case relates to invalid Blowfish options, but could possible be expanded in the future. (While not in the documentation, bug #64449 indicates that a "failure" should be returned for algorithms whenever the salt is invalid.)


The rational that the salt is never returned may be linked to bug #55439:

If crypt() is executed with MD5 salts, the return value conists of the salt only.

The consequence is $valid = crypt($pw, $crypt); is TRUE, for any $pw.

Thus, by ensuring the salt itself is not returned it avoids a feedback cycle where stored hashes - just the salt from due to the bug - would always register as being valid for any password. The restriction that the salt is not returned may mitigate degenerate interactions of different (patched and unpatched?) servers.


Also, anyone know how to find point documentation for specific PHP versions? It would be interesting to see when the "differ from the salt" clause was added ..

user2246674
  • 7,621
  • 25
  • 28
  • Ok.. so short string ->fail.. but the rest... "and is guaranteed to differ from the salt on failure"...ok so if it fails we receive the short string and it is also guaranteed to differ from the salt? Why is this important information? I don't understand why I would want to know that...? – fast-reflexes May 25 '13 at 09:40
  • @fast-reflexes I updated my answer with the only somewhat rational explanation I could find. That is, I believe it's simply a hack to fix a bug and the whole crypt API is degrading into a mess to support current usages. Who checks the return value of crypt anyway? Why doesn't it throw an exception on a critical failure? I guess at least, if the salt isn't returned, the users will never be able to log in and someone will have to [quickly] address the issue. – user2246674 May 25 '13 at 19:36
  • Thanks, good explanation! Basically one SHOULD check the result of crypt() and confirm it's 13 characters or longer before one insert the generated password into the db then... Wonder when it fails then, it seems to fail when given salts that contain illegal characters... wonder if there is any limit when it comes to characters in the actual password? – fast-reflexes May 26 '13 at 09:58