Edit: Here's a post on the matter http://www.zdnet.com/blog/facebook/facebook-passwords-are-no...
* "pAssword" - the password as it is
* "PaSSWORD" - the password, case inverted, in case you have caps lock on
* "PAssword" - the password with its first letter capitalized, for those with mobile devices that insist on Capitalizing Everything.
Something inline this: https://github.com/bungle/web.php/blob/master/password.php#L...
Also, why is there no salt in the comparison. It calls a naked crypt, that whole ... interesting ... hash() function is sitting there unused.
I have serious doubts whether this code actually serves the user's interest - despite trying to be cute and helpful
1. When user registers, his password is hashed with that hash-function, and that hash is stored in a database (it uses random salt).
2. When user tries to access the site, a password is hashed against the hash stored in a database, and it should return same hash if matched (this is how crypt works!).
3. In non strict mode we try also two different passwords to match the hashes (just like Facebook does).
Code example:
1. $hash = \password\hash('user entered password'); // store it to db
2. retrieve hash from db, and check it:
$valid = \password\check('user entered password', $hash, false);
3. // Now these passwords are valid:
'user entered password' // == correct form
'User entered password' // == Mobile browser capitalizing first char
'USER ENTERED PASSWORD' // == CAPS LOCK on
And one line example:
$valid = \password\check('user entered password', \password\hash('user entered password'), false); // == true
One way to resolve that issue is to create two versions of the password (one with normal casing and one with inverted casing, but both with the first character lowercased), sort them, and pick the first result.
["pAsSwOrD", "PaSsWoRd", "PAsSwOrD"].map(function canonicalize(pwd) {
function invert(str) {
return (str == str.toUpperCase()
? str.toLowerCase()
: str.toUpperCase());
}
var head = pwd.substring(0, 1).toLowerCase();
var tail = pwd.substring(1);
var vers = [head + tail,
head + tail.split("").map(invert).join("")];
return vers.sort()[0];
});
Which gives the following result: ["pAsSwOrD", "pAsSwOrD", "pAsSwOrD"]
The three different variations get canonicalized into one version. With it, you can just store one hash instead of three.