Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> If users created or changed their password after March 14, 2012, it is hashed with a function called bcrypt. If users have not changed their password since then, it is uniquely salted and hashed with SHA-1.

This is a common mistake.

Don't ever do opportunistic upgrades. Instead, upgrade all at once and retain "legacy" metadata needed to re-authenticate the user until their password hash is rotated. https://paragonie.com/blog/2016/02/how-safely-store-password...

Beyond that: Bcrypt is great, SHA1 is terrible, and the level of technical detail in this advisory is excellent. The fact that I was even able to critique their 7 years old security decision at all speaks volumes to the transparancy.



I think their main mistake was requiring a user to change their password to upgrade the hash instead of upgrading the hash on the next user login.


What if there wasn't a "next user login"? You'd hold onto insecure hashes possibly forever.

Don't make this mistake. Rehash all of them up front.

The details of whether or not users are forced to change their password is irrelevant to the escape route from this trap.


How are you going to rehash them without having the cleartext password? Hash the SHA1s to bcrypt and then check every password's bcrypt and SHA1*bcrypt's password from then on?


It’s explained in the linked blog post in the chain you’re replying to, but:

- Set all password hashes to Bcrypt(existing SHA-1 Hash)

- Create a new flag column to track whether the password is upgraded to straight Bcrypt.

- If flag is false, compare stored hash with Bcrypt(SHA-1(user input)). If it matches, log user in and replace stored hash with Bcrypt(user input). Set flag true.

- If flag is true, compare stored hash with Bcrypt(user input)


Genuine question: does hashing with algorithm B an existing hash computed with algorithm A solve anything at all ?

I mean, A’s hash collision issues will just be applicable as well into B’s space, right?

And I would go for rehashing at next login, and, after a while, identify and disable (no login possible) the legacy accounts with their deprecated hash, forcing users to change password at their next login (if it comes one day, that is).

(Also, I would not use a Boolean, but some integer to identify what is the current algorithm to use, to cope with future deprecation, but really a small implementation detail here)


> Genuine question: does hashing with algorithm B an existing hash computed with algorithm A solve anything at all ?

Absolutely. It solves by far the #1 threat against password hashes when they get leaked.

Algorithm A here is SHA-1, which is very fast to hash, which makes it completely terrible for password hashing -- when an attacker gets their hands on the hashes and salts, with a halfway decent GPU they can dictionary attack and recover even very long passwords in just a few hours, and then merrily use the same password get into the email account, because to a first approximation everyone is terrible about password re-use.

Algorithm B here is BCrypt, which is very very insanely slow to hash, so the same attacker would need years/decades to recover the passwords from the hashes.

HashAlgorithmB(HashAlgorithmA(input)) is dominated by Algorithm B's runtime, so it is equally very very insanely slow to dictionary attack the hashes.

> I mean, A’s hash collision issues will just be applicable as well into B’s space, right?

Sure. But the threat here isn't collision generation at all -- that's more of a PKI infrastructure concern.

Nobody is worried that the guys who have these SHA-1 hashes are going to sit around generating collisions -- that would be slow and stupid, the collision would only apply to other SHA-1-using websites that use the same salt. For this reason, nobody cares about password collisions for leaked password hashes.

They're just going to throw dictionaries + listed salts into a GPU and generate SHA-1s at a rate upwards of 68 billion per second on a cheap GeForce 1080, and quickly reverse the entire table. That gets them into every site the same password was used for, no matter the hash function.

This is how all of those leaked password DBs get generated, and this is why people say “don’t use SHA-1, use BCrypt for passwords” in the first place. It’s all about speed being bad, not collisions.

This is the threat BCrypting SHA-1s guards against.

> And I would go for rehashing at next login, and, after a while, identify and disable (no login possible) the legacy accounts with their deprecated hash, forcing users to change password at their next login (if it comes one day, that is).

You're still keeping easily-reversible hashes around for some period of time that cost users control of passwords if-and-when they leak before you wipe them. You can do better with zero downside. Get rid of them all immediately.


Yep, I see, it makes total sense. Thanks for the explanations!


I don't think that'd work in this case since the SHA-1 was salted, so you'd need to store the SHA-1 salt in a separate column, then calculate Bcrypt(SHA-1(input + salt)), right?


Obviously they had to be storing the salt to begin with, so yes you’d keep using that salt column and use user input+salt as the input to SHA-1.


The legacy_password flag can also be a text field containing a salt. If it's empty, you have a non-legacy password.


Yes, and slowly upgrade from bcrypt(sha1(password)) to just bcrypt(password) as uses reenter their password. Do the same when you finally upgrade from bcrypt to whatever is next. No harm in specifying the encryption 'state' in your database for each user.


Half measures are not solutions. Keeping insecure hashes on hand was the main mistake, full stop.

They'd still have leaked all of the insecure hashes of people who never logged in after the change in 2012 -- and that's still not good enough.

Immediate remediation means never keeping toxic hashes on hand, and never having to say to any subset of your customers "Sorry, but your password has been compromised due to our incompetence".


Popped in to say exactly this.

If you ever come across insecurely hashed passwords in your career, always remediate all of them with a second more secure hashing strategy at once.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: