views:

211

answers:

8

I am not a security expert... so I might be very wrong here.

Am I right in that the only advantage to using a stronger algorithm is to slow down password cracking?

In which case they must have the password hash and so will have already comprimised my database right?

As I do not store any thing of real world value what is the point in using a strong password algorithm? If they are already in my database they can change anything they want so why would they want the passwords?

The only reason I can see would be to slow down brute forcing and to secure my users passwords in case they use the same one for their email accounts...

I have implemented SHA256... but I am wondering if it was worth it

A: 

If the password is crossing the wire in any unencrypted way (e.g., it's a password for a web app running on a non-SSL server), then they wouldn't necessarily have access to your DB, just to the wire traffic. So in this case, you'd want to make sure that password was as protected as you can get it within reason, hence using something stronger than MD5.

delfuego
If you are not using an SSL connection on a password field then unless you are using some sort of javascript based encryption I do not see how the choice of MD5 server side would make a difference? Unless you mean the hash is stored in a cookie?
Mark
+2  A: 

Yes. If someone gets your database with your passwords in it, using something stronger than MD5 will slow down their ability to do a dictionary attack against the whole thing. The really important thing you need to do along with this that increases security by leaps and bounds is to add a salt to your passwords before hashing them.

Basically you should read everything that's pertinent to what you're trying to do at http://www.owasp.org and follow it to the T, unless you count yourself as a security researcher.

Michael Della Bitta
+10  A: 

MD5 isn't encryption, it's a one-way hash.

The only purpose of using a better one-way hash is to delay reversing the password. As computers have become more powerful and vulnerabilities in various hashing algorithms have been discovered, better hashes must be developed.

In which case they must have the password hash and so will have already comprimised my database right?

The purpose of salting and hashing passwords is to protect the password itself, even in the event of database compromise. Many (most) users use the same password for multiple logins, so if it's compromised, so is every account it's linked to.

SHA-256 should be more than sufficient, but make sure you're also salting the passowrd. Your functions should look like this (pseudo-code):

fun store_password(plaintext):
    salt = random_alphanumeric(40) # maybe put 40 in a config, or #define somewhere
    hashed = sha256_digest(salt + plaintext)
    return "sha256!" + salt + "!" + hashed

fun check_password(plaintext, stored):
    algo, salt, hashed = stored.split("!")
    if algo == "sha256"
        return (sha256_digest(salt + plaintext) == hashed)
    else if ... # other supported password schemes here

A commenter below pointed out that with a sufficiently powerful attacker (or, weak passwords), storing the full salt might allow the plaintext to be brute-forced. If you're concerned about that, use a two-part salt. Generate part of it every time (saltA), and store the other in a config file (saltB). Then combine them to generate/check passwords:

import my_config

fun store_password(plaintext):
    saltA = random_alphanumeric(40)
    hashed = sha256_digest(saltA + my_config.saltB + plaintext)
    return "sha256!" + saltA + "!" + hashed

fun check_password(plaintext, stored):
    algo, saltA, hashed = stored.split("!")
    if algo == "sha256"
        return (sha256_digest(saltA + my_config.saltB + plaintext) == hashed)
    # ...

Note that if you choose this system, changing your saltB will invalidate every stored password.

John Millikin
Just to throw this out there, John -- you say that the purpose of salting is to protect the password in the case of DB compromise, but it appears your example stores the salt in the DB in the same field as the (hashed) password.... so in this case, salting doesn't help you at all.The only way that salting your passwords helps you in the event of DB compromise is if the salts are stored external to the compromised DB (e.g., in the app itself, or in another persistent source).
delfuego
+1 Recommend SHA256 also
Xeoncross
delfuego: that's not true -- salts protect against pre-computed tables of hashes (aka "rainbow tables"). By salting the password with a sufficiently long salt before storage, it forces the attacker to use a brute-force attack. Assuming the user didn't use "123" or "password" for their password, it should be quite secure.
John Millikin
The salt helps prevent against rainbow table attacks as the hash will be unique to the password.
Mark
It does help - it makes the cracking of the hashed string harder.
Dani
Though, if you're concerned about somebody with a super-computer who *can* brute-force your hashes, an additional salt in the config file might be a good idea. I'll add that to the answer.
John Millikin
You're right, I was a bit general when I said "doesn't help you at all" -- it doesn't help you against rainbow tables. But if a DB compromise reveals your hashes AND salts, then you're still susceptible to brute-force attacks, which you just acknowledged in a comment so I'll stop typing. :)
delfuego
I already am using a random salt stored in a separate column, Thank you John.
Mark
Its difficult to pick an accepted answer as they all add something, however you are without a doubt the most thorough. I think I will stick with a single random salt except I will hash the password and then add the salt and hash the whole lot. That way I figure I can use a shorter salt. What do you think?
Mark
Double-hashing doesn't add much extra security; if you're concerned about somebody with lots of CPU time trying to brute-force your hashes, it's better to just add more salt. And don't worry about the length of the salt -- an extra 30-40 bytes per user record is irrelevant unless you've got millions of users.
John Millikin
2 points from me1) A salt is meant to be cryptographically random, simply generating a pseudo-random string of alphanumeric characters partially invalidates the salt2) The specific question was on the weakness of MD5 to collision attacks which is now completely though still requires some computing powerI agree on SHA 256 though. SHA1 is also looking shaky. All depends on what you're protecting and what the risk is though
zebrabox
@zebrabox: as long as the random source for picking alphanumeric characters is correct, the salt shouldn't be invalidated. Every major OS has a means to read random data from the environment.
John Millikin
+1  A: 

Don't use MD5 for cryptographic purposes - it's broken! Use the SHA256 you implemented, or better a library widely tested (I bet you missed many security issues in your implementation).

BTW: cryptographic hash functions are built such that you cannot decode the initial text. Encryption always you to restore the original text only if you know the password.

Alexandru
Could you recommend such a library?
Mark
The collision attacks on MD5 are generally not applicable to password hashing uses. But it never hurts to be paranoid :)
bdonlan
It's not about collision attacks. Please check en.wikipedia.org/wiki/Rainbow_table. I've been to a few security seminars and all of them started with: MD5 is broken. @Mark: what programming language? Python already provide them as part of the standard library. I believe Perl provides them, too.
Alexandru
A: 

If you enforce better passwords it will do the job without changing the algorithm. md5 should not be reversible, at least not to a wannabe novice "hacker". using good passwords (longer than 12 chars and using both numbers, capital and small letter) will do a better job than changing the algorithm.

@John Millikin had good point about salting the password - which is even better than just enforcing good password.

Dani
I hate, hate, *hate* password requirements like this. Why should the web developer foist their job off on me? Better to accept whatever password the user chooses, salt it, and store it -- with a sufficient salt and appropriate algorithm, the database will be immune to both brute-force and rainbow table attacks.
John Millikin
I actually edit the post before you posted this comment, I agree with you on that.
Dani
+2  A: 

Using a stronger algorithm is probably worth it.

First of all, most users of MD5 are probably using a library that has been tested and reviewed. A lot of these libraries are no-cost and open source. And most of these will also provide SHA-1, and maybe even the SHA-2 algorithms.

So, the "cost" of using SHA-1 or SHA-256 is likely to be very small.

On the other hand, what is the value? Even though an application might not contain much data of significance, and a compromise of the password table is likely to include the rest of the data anyway, it helps to remember that most passwords are used for multiple applications. Even though the user might not care about your application getting hacked, they will be upset if that gives the hackers access to the password they also use for banking.

I think that it's worth upgrading to a better hash algorithm.

Also, the motivation for ditching MD5 in favor of SHA-1 or SHA-256 would be that MD5 is "broken." There are shortcuts to find hash collisions, so that brute-force isn't required. To slow down a brute-force attack, you also need to use a key-strengthening technique. Usually, this means repeating the hash operation a few thousand times. You'll also need to use a random salt to thwart pre-computed lookup tables, like rainbow tables.

Of course, algorithms like the key derivation algorithms in PKCS #5 spell out in detail a secure way to "hash" passwords for authentication tables. Using a standard like that will give you access to high-quality analysis of your chosen technique, and alert you to potential vulnerabilities. You are also more likely to find implementations that have already been widely reviewed and tested.

erickson
Sure, I was not really considering ditching SHA256 for md5. Sorry I didn't make that clear, it was more hypothetical. My point was, what is the big deal about the algorithm... if they have access to the hash then they are in your database already. You are right though in that the reasons I stated are enough of a reason to use a stronger algorithm, but we are talking more about damage control that security if we are talking about the risk of a users password comprimised that they use elsewhere.
Mark
+4  A: 

Jeff has a great post titled You're Probably Storing Passwords Incorrectly which addresses the issues surrounding this type of password storage. Highly recommended reading.

Greg Hewgill
That was informative.. thanks
Mark
+1  A: 

Yes, SHA-256 is recommended for passwords. In fact for secure US government software it's mandated by NIST starting in 2010.

See http://www.openssl.org/ for a free, open-source cryptographic library that's validated by FIPS. It implements message digest algorithms, including the SHA-2 family.

There are still legitimate uses for MD5, SHA-1, and other hashing algorithms of lesser strength, but they are not recommended for hashing passwords.

Bill Karwin