18

Given the known weaknesses of MD5 and the recent (May 2009) weaknesses discussed in SHA1, how should new programs be salting & hashing their passwords?

I've seen SHA-256 and SHA-512 suggested.

Programming predominately in Ruby on Rails and using PostgreSQL -- but other languages and environments might also have to calculate password hashes.

1
  • 2
    Thanks Martin, I do understand that. It was a narrow question and deserved a narrow answer. Commented Jun 2, 2010 at 6:22

4 Answers 4

20

SHA-256 and SHA-512 are safe for the foreseeable future. They belong to the SHA-2 family, against which no attacks have been identified so far. This wikipedia page says that Unix and Linux vendors are just now moving to SHA-2 for their secure hashing of passwords. The SHA-3 family, with even stronger algorithms, is being developed, but won't be ready until 2012 at the least.

P.S: Unless you're hiding secret agent names from governments, you'll be safe with SHA-1 as well, but if it's no trouble implementing SHA-2, just use that one instead.

Sign up to request clarification or add additional context in comments.

6 Comments

PKCS#5 (rsa.com/rsalabs/node.asp?id=2127) discusses some other good information (like iterations) that the reader may want to consider.
@Noon Silk: how much computing power is currently required to break it?
@Noon Silk: according to that page, the break is currently just theoretical (i.e. something a bit faster than brute-force/birthday was found. That said, my original post is from a year ago and a fully expect the P.S. to become really wrong not too far into the future
@Eli: Note that the attack is also from 6 years ago, so it's not clear what has progress since then. I mean, your main post is good, and I haven't downvoted you, but I just disagree with your final sentence. Probably no need to keep discussing it; my comment is made and information provided.
100 modern PCs can bruteforce a 8 characters long password from it's sha256 hash within 1 day, using sha256 for passwords today is not much different from storing them in plain text
|
18

Use a slow function like bcrypt. Here is a post from the Phusion guys.

Comments

9

You should use a password-based key derivation function as the uid/pwd result; the most werll known is PBKDF2 http://en.wikipedia.org/wiki/PBKDF2 also defined as RFC 2898 https://www.rfc-editor.org/rfc/rfc2898. PKBDF2 takes your secret data as well as a salt and an iteration count. This is the standard way of solving your problem.

If you program in .NET, use Rfc2898DeriveBytes https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.rfc2898derivebytes

1 Comment

I've just read 100 articles & questions on the subject, and it seems agreed that RFC2898 or any other multi-iteration solution (ex. BCrypt) is the way to go. But Rfc2898DeriveBytes is based on SHA-1, no? Doesn't it make outdated? And BCrypt doesn't seem "validated", even though it looks great. Also, Rfc2898DeriveBytes doesn't implement IDisposable, it looks like it could leak the plaintext password in memory pretty easily. My actual needs are not that paranoid, but I want to measure how safe each thing is. What would be your take on that? Thanks!
-4

You should use a hash username, password and salt together, like:

hash(length(username)+"_veryuniquesalt4rtLMAO"+username+password)

That way, your database is not vulnerable to any existing rainbow tables, because of the salt, and with the username hashed along with the password it is also impossible to create a rainbow table for your specific hashing method.

Using a "slow" hashing algorithm will secure the passwords better, just like if they were more complex, but it is a tradeoff, once you have decided on a certain level of slowness you can't just scale back when you need the performance for other things.

It is also possible to do the slow hashing clientside using JavaScript, that way it is not going to be a performance issue, but the method will of course require JavaScript to be enabled.

No matter what you choose, a little slowhashing is far better than nothing, use 1 millisecond instead of 1 microsecond and your protection is 1000 times stronger.

You can use bcrypt, or you can make a conventional hashing algorithm do a lot of extra work, just make sure that the extra work isn't primarily string concatenation.

In the end, better not get your database stolen, a lot of passwords are so weak that they are easily extracted no matter what you do.

7 Comments

Note that including the username in the hash prevents changing the username. Depending upon the system requirements, this may or may not be desirable. In cases where it's not desirable, use of the uid (or guid, or equivalant) would be an alternative.
You would just have to make the user enter his password to change username, best practice anyway.
there's a very subtle bug in your code - you should never concat data in a hash. H(x + y + z) opens you up to a Length Extension Attack. Rather you should: H(H(x + y + z)) or H(H(x) + H(y) + H(z))
This isn't very good advice (the salt should not be a constant string - there should be one salt per password, and it should be randomly generated each time the password is changed) and it doesn't answer the question anyway, which is specifically asking about which hash function to use.
What needs to be said about algorithms has been said, there is no need for me to parrot what other people have said. Username + site specific string makes for a completely unique salt, it'll never get better than that. Your method achieves the same, but nothing more.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.