The comment thread on Reddit, which the article references, is definitely worth reading. There's some good discussion about the difficulties involved in upgrading people's hashes to use a more secure system (eg: http://www.reddit.com/r/WTF/comments/f96w7/amazon_security_f...)
Is there a good way to update passwords to a new encryption scheme? the article tries to ding amazon for failing to do this, but I can't think of a way to reinforce the passwords without announcing that there's a flaw in the implementation. Is there a standard way around this?
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.
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 done deliberately, could this be a useful feature so that users can typo a password (say levenshtein distance <= 1 or 2) and still login? Obviously the major downside is that you would need a longer password to get the same level of security and it could be difficult to implement especially since the password should be hashed. Is this feasible? I'm guessing the answer is no, but was wondering what other people thought.
Only if you want to store all the passwords in reversible encryption* or do some crazy scheme which you check every possible combination of hashes within the distance of the current password.
* If I find out you've been storing passwords in plain text I will hunt you down and slap you. :)
My guess is the average Amazon user isn't going over 8 characters and aren't using multi-case passwords to begin with. While stronger passwords would be ideal, most non-savy people are still going with "password", "letmein" and "123456" which aren't secure under any hashing schema.
What exactly does this hurt? It cuts down on customer-support traffic, makes life easier for the user, and (as far as I can imagine at least) doesn't make anyone any more vulnerable. Under a fuzzy comparison scheme, weak passwords are still weak, and strong passwords will still be strong.
A strong password that gets a lot of its strength from length and mixed case will not still be strong under this error.
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.
I couldn't replicate the article's results for the 8 character cutoff, but I did verify my password is case insensitive. For the record, I registered in 1996 or so, and probably haven't changed my password since.
[+] [-] nbpoole|15 years ago|reply
[+] [-] tel|15 years ago|reply
[+] [-] nbpoole|15 years ago|reply
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:
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.
[+] [-] jmillikin|15 years ago|reply
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.
[+] [-] rookie|15 years ago|reply
[+] [-] johnswamps|15 years ago|reply
[+] [-] epochwolf|15 years ago|reply
* If I find out you've been storing passwords in plain text I will hunt you down and slap you. :)
[+] [-] joshfraser|15 years ago|reply
[+] [-] rabidsnail|15 years ago|reply
[+] [-] unknown|15 years ago|reply
[deleted]
[+] [-] unknown|15 years ago|reply
[deleted]
[+] [-] pieter|15 years ago|reply
[+] [-] ronnier|15 years ago|reply
[+] [-] unknown|15 years ago|reply
[deleted]
[+] [-] goombastic|15 years ago|reply
[+] [-] flawawa2|15 years ago|reply
[deleted]
[+] [-] CamperBob|15 years ago|reply
[+] [-] RickHull|15 years ago|reply
I think you meant: strong passwords will be truncated down to 8 chars, making them weak.
[+] [-] jackowayed|15 years ago|reply
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.
[+] [-] earl|15 years ago|reply
[+] [-] dkarl|15 years ago|reply
[+] [-] corin_|15 years ago|reply