Amazon.com Security Flaw Accepts Passwords That Are Close, But Not Exact
wired.com
wired.com
The standard way I've seen is to do this when the user logs in: if in checking their password you notice they're using the old hashing scheme, you use the plaintext password provided by the login process to generate a hash using the new scheme.
For example, lets say you're a PHP function that takes in $username and $password (both plaintext). You're "upgrading" from unsalted MD5 to unsalted SHA1 (NOTE: DO NOT DO THIS IN REAL LIFE. READ http://codahale.com/how-to-safely-store-a-password/ AND UNDERSTAND WHY UNSALTED MD5 / SHA1 SHOULD NOT BE USED FOR PASSWORD SECURITY). Your code to upgrade the hashes would look something like this:
if (md5($password) === $cur_user['password'])
$cur_user['password'] = sha1($password);
Now, you may have realized that there's a flaw here. Since the server uses the hash for verification, it can't be 100% sure that the plaintext password is actually correct. If there's a collision (two plaintexts hashing to the same value), you could inadvertently store the wrong password in your new hash.In this case, the problem is that passwords longer than eight characters are silently truncated. So, if my password is something like supersecretpassword, I could also enter supersec and have it accepted (since they hash to the same value). That would be a problem for Amazon, since someone could make a typo in their password and have the wrong value stored in the new hash.
Not really. It's more of a fundamental property of hashing functions, and it's technically true of any hashing function, and collisions are nearly just a technical possibility unless you're using an incredibly-small hash output. Though that would likely be preferable to truncating before hashing - fewer practical collisions and safer, as reversing the hash is less useful due to more collisions actually existing in breakably-short password lengths.
1. They could force everybody with an old password to reset it. This would announce there was a flaw, but shouldn't be any riskier than having a "forgot password" link.
2. Silently upgrade passwords as users log in. This is risky, because many users might not log in for months.
3. Use their clusters to reverse weak password digests. This would be mostly transparent to customers, but runs a risk of accidentally locking out some customers. For example, if "bar" and "foo" both crypt() to "abcd123", and the user has password "foo", the recover-and-redigest method might change the password to "bar".
4. Wrap old passwords in a new digest -- presumably they have some way to determine which algo is used per-user. They could treat the output of crypt() as the input to a more secure digest, like scrypt, and then just store "crypt-plus-scrypt" in their database as the digest type.
* If I find out you've been storing passwords in plain text I will hunt you down and slap you. :)
For example, 8-character alphanumeric passwords:
((26*2)+10)^8 / (26+10)^8 = 77.4
You have 77 times fewer passwords of length 8 (probably worse than that, most people skew more towards letters than numbers), so it should take 77 times longer to test one.
PS: Try it: ASdf becomes asDF.
My Mac is running Windows at the moment and I can't reboot into OSX to test for several hours, so someoneelse will have to confirm or deny this.
If that's the case, you're doing it wrong (it being password hashing). Because if you can hash 1000 passwords fairly quickly, that's the lower bound of what a dedicated attacker can do. ;)
I think you meant: strong passwords will be truncated down to 8 chars, making them weak.
See http://news.ycombinator.com/item?id=2003888 or http://news.ycombinator.com/item?id=1545576 for examples of how fast certain types of brute-force attacks have become.
For example, the password fOoBaRbAzbArBaZFoO would be a pretty strong password. foobarba is much weaker, and this error would make foobarba (and foobarbaz, etc) work.
(and if they can, some browser password auto-save feature is going to screw you anyway so it doesn't matter)