views:

200

answers:

7

I am by no means a security expert or even a novice. I'm a newbie at security at best.

Someone suggested I use SHA1 instead of MD5 - why would I choose one over the other? Is one more secure?

A: 

MD5 has been "broken", and higher levels of security now require SHA-2, actually. It's a quite interesting read here http://en.wikipedia.org/wiki/MD5.

Edit: 9 seconds late :)

luggage
+1  A: 

Whichever you use, use salted hashes.

Good luck.

Ian P
+1  A: 

storage is cheap and processors are fast. use a 1 kilobyte salt with SHA-512.

Ysangkok
A: 

SHA2. Scheier has some new alternatives too

Jay
+7  A: 

I would use SHA2(256) at the minimum - however:

There is little or no point in simply hashing a password in a database due to rainbow table attacks. Equally, salted hashing is better, but if someone has access to your database, then the chances are that they have access to your code in which case they can probably disassemble a fixed salt. Equally, if you use a random salt, then you're storing it inside the row anyway, so while it slows people down they can still attack it with a rainbow table.

A better solution is to use Password Stretching which uses a random salt as well as a random (high) number of iterations so that attempting a brute-force attack against each password takes significantly longer and therefore makes it physically harder to crack all the passwords.

I believe in .Net this can be achieved using PBKDF - but I've mislaid a link to it (somebody supplied it to me an answer to a question I asked a while ago). EDIT-Found the link for .Net: Rfc2898DeriveBytes Class.

On MD5

Whilst MD5 has indeed been shown to be 'broken' as mentioned by the other answers, the main reason why I wouldn't use it - and why I've read that it's inadvisable to use it - is because it's actually very fast, thereby increasing the possibility of a crack within a given period of time.

Andras Zoltan
+1. This is the only answer that got it right so far.
dtb
Passwords are silly. If you want definite (albeit, not proven) security, you should use client certificates. Passwords will always be broken no matter what once the attacker gets your database, for instance, he could setup a logger to log the passwords before they are salted and checked against the database if he has control over the right spot. Or he could just mount a parallel bruteforce attack on the hash. Then again, you _are_ usually basically screwed once the attacker owns anything in your infrastructure.
Longpoke
Even if you had a password that was too long to bruteforce the hash for, you probably don't have that password on any other site (if you do, you already lost). If you don't have that password on any other site, then there is no point in hiding it from the attacker really as he this is security through obscurity at best. Think about it, the only case this will save you is if the attacker could only get read access to your database, and for some reason can't hijack sessions from reading from your db (say, the session resets on IP change). That is a very unlikely scenario.
Longpoke
If or if not "passwords are silly" depends on the asset you're protecting. For a average website it's quite unlikely that a random attacker owns anything in the infrastructure, tortures the admin, etc. But it's quite likely that the database is leaked to the general public due to a stupid programming or configuration mistake. For that case any scheme that uses any key strengthening is good enough.
dtb
@dtb: Actually, everything I just said applies to mainstream public sites. I didn't bother to go into niche security needs, I was talking about the typical case. Random public sites get owned all the time, popular or not. The attacker will stacksmash, XSS, CSRF, SQL inject the site and will probably be able to write to the main page and sniff passwords. Most of the hashed password list will be cracked within minutes (unless you have a hash that takes an hour to compute? well then nobody is using your service [the attacker has a few magnitudes more computational power than you]).
Longpoke
@dtb: The fact is, in most cases, password hashing doesn't help at all, besides _possibly_ delay the attacker for a bit. If a site is crappy enough to hand over your password list, the site is crappy enough to be completely owned.
Longpoke
@Longpoke - you can always argue for a way that somebody can breach any security; but in the context of this question it's actually a red herring to be going on about xsrf etc as many of these are down to client security. As for infrastructure hacks - if a hacker got access to our infrastructure in that way they'd more interested in all the financial account details we have before they even think of some passwords. As for client certificates? Seriously? 'Definite' security? Really? There is no such thing - and it's irresponsible to suggest otherwise.
Andras Zoltan
@Andras Zoltan: I don't get what you mean. I want to know an actual valid use case of password hashing. Password hashing IMO implies that you are authenticating to multiple services with the same password, in which case a client certificate would be better since one service getting hacked only lets the attacker tamper with that service. Password hashes being readable to the enemy is game over, period. To prove otherwise, can you hand me over a copy of your password hash column?
Longpoke
@Longpoke -- here you go: My password hash is "2pVji9p6NbnWV2SebMK9TruOdvsVIbenBF+fX3PJfXdv/DyBlgTpkv1tKsgGVpjzDyHoVUEvzhzZL30mIWmiYOSZ6FcN6BJeWPrP4lCxZ4J1lmSL8MEYDyNHVFwS05LsH5jpdCir7ew32cBLaTB84a1exmuvsim97l1H6rsx+EquMRlXg1HP9SKrjqfIWMZ4XFa4cbP8r469kZjtdkTlVEMCDtzkL8IjyfPYKKDycKrgVHDiU9X/qFgY3tgkSME0TmRukyCfzQUIkRB6kBaB7R63aPr/cs2OmfbggNL3SlLeQoNwcijKW0TuWQX4UfQY3e/uIcoDd4C8ldYN4wgCUA==". Its calculation took {00:00:00.4656027}. It's a word that can be found in the English dictionary. If you can tell my password within a reasonable time frame I'm honestly impressed :)
dtb
@dtb: Too much work. And it looks like a custom hash (or RadioGatun?). For a public site, I'd register with my own password "A" and get the hash of it and brute force every possible permutation of composed hash functions until I find the correct function, or if that fails, register a bunch of accounts and analyze the change of H("A"). If that fails, hack the users on other sites and get their passwords and analyze against their hashes on this one, and if that doesn't work, just do the same thing as the first method but for a group of unknowns, since some users would have weak passwords.
Longpoke
@Longpoke: It's 3 lines of C# code using only standard .NET classes. If that's "too much work" then I guess that I've just proven that these 3 lines are perfectly enough to protect my asset. In case you still want to try, here is the hash of "A": "3ZyM1YZhl8bFf6x99xDDBsPbm18givBckaAU561gDtHCMIwTT2urk8Z88L8f9sDaYjfpFJi06Wl3g5i4HlaAGTP4+ADkkWHPasFVQuQ3zKjVWpOPkE40H6D7Crk3xnKjAF5bzgfeyiqupa0OKMuYrzUuYA19ypJjo4+mz++6eJbjD4/HhKFfFrpieZtSRTWk6EBy3Xd4py9bur+uDaJI6pnRJC4UYBmvF4H9fd1NkHnrG6axut3+/WSq63R0UABpAk5g8C6ym0SRPfv6QJY7OFAPsk9QcBZGV5Lyl9XGn0qTjktXrizIypgnKHXku7Z78+FeqQ1/YtpPPvMIualJhw=="
dtb
@dtb: I only had time to try combinations of 4 iterated sha512s concatenated. I'm guessing you used an HMAC so it's not even worth bothering... What I said still works a lot of the time. But anyways chances are if you can get the database you can probably get the HMAC key anyways...
Longpoke
@Longpoke: you don't know what you're talking about.
GregS
@GregS: orly. Tell me some use cases where the attacker can obtain the full list of password hashes but not recover them. The only way would be for the salts to be stored somewhere else (if they are the type of salts that can be used as secrets and not just to deter preimage).
Longpoke
@Longpoke: No, I won't do that. You're just making wild conclusory statements that, when you examine the details, show you aren't familiar with the concepts.
GregS
@GregS: You are trying to quantify my intelligence in a field while you have said _nothing_ with respect to it. What's the point in hashing passwords, when the attacker can already has full read access to your database, and all the goods are in the database? Is it because the users use the same password on multiple sites? In that case, they are already doomed. Is there another reason for hashing? Perhaps your infrastructure calls for it, if so, I'd like to know.
Longpoke
Otherwise, my conclusion is that people will just hash their users' passwords for no reason, other than thinking it gives them some sort of extra security, which may be the case, but at best this will only delay an attacker. So if you use some highly iterated hash, you are basically just wasting your CPU time.
Longpoke
In the case of HMAC, the authenticator needs the HMAC key to verify the HMAC as well as the previously computed HMAC of each user. It is probably a bad idea to have copies of this database on other compromisable points. So I'm assuming most of the time, the HMAC key and HMAC list will be stored together, so if the attacker can obtain either of these, he _probably_ has access to the other. Additionally, the attacker might be able to sniff passwords on the authenticator as they fly by in plaintext. So what is the point in even defending the passwords when the authenticator is compromised?
Longpoke
Is the point in defending the passwords because you have other authenticators that share the same credential list? This is what client certs are for! If one authenticator gets owned, the other authenticators are still guaranteed to be safe (assuming nobody can crack popular PKI). This is simply not the case with hashing, there is always a bit of risk with hashing, especially against raw brute force (think botnets and GPGPU against your puny thing that has to be calculated within a second, or people who have dedicated hardware)... Please, can someone explain to me where I am wrong?
Longpoke
@Longpoke: A valid use case: A website used by people where they can register and log in on any web-enabled device with a password. Oh, that'll be most websites then. And you keep banging on about hashing-this answer (which comes straight from experts) rejects hashing for the exact reasons you specify. Using the password 'A' will not help you crack all the the passwords in a db that uses stretching correctly - did you actually read the link I included? What exactly are your credentials in this field? And before you ask mine - I have none, but then I'm not claiming to have all the answers,u r
Andras Zoltan
@Andras Zoltan, yes I know what key strengthening is. And I'm done wasting my time here, as you are all just saying silly things. The "use case" you gave is not a use case, it's generic, and in most cases the password hash doesn't protect **anything** because the attacker doesn't care about the passwords and if he does he can still most likely obtain them since he already owned the authenticator.
Longpoke
Oh and here is my "credentials" in the field. A few years ago someone stole a product from me, so I hacked their site and planted a backdoor in their PHP code that will log the passwords _before_ they are hashed and checked. http://longpoke.blogspot.com/2008/11/crysis-wars-crysis-hack-now-availible.html?showComment=1240761366499#c8385619622646577747
Longpoke
@Longpoke: Real problems require real solutions. There is a reason why passwords have survived as the only universal means of authentication in common use. But you have posited client certificates as a superior solution. What happens when you need to authenticate from a different machine? Client certificates are not portable. So how do you fix that? And yes, I'm setting you up.
GregS
`Equally, if you use a random salt, then you're storing it inside the row anyway, so while it slows people down they can still attack it with a rainbow table.` - For a 256-bit salt, the rainbow table would need more bits than there are atoms in the universe. You can always make something *"more secure,"*, but this is the point most sane people stop and say *"Secure enough!"*
BlueRaja - Danny Pflughoeft
+3  A: 

MD5 and SHA1 are both considered insecure, with SHA-1 being better. However, there are 2 things that you should consider:

  1. By "insecure", they mean to say that it's mathematically easier than brute force to determine the pre-hashed value. Sometimes this means they could cut it down from a billion computations to 900 million, other times it's significantly less. This is nowhere near as insecure as my point #2.

  2. Because you are creating a hash, it's easy for a hacker to determine your database's passwords by populating a table full of common passwords, and running it through the same hash algorithm, regardless of which one you use. This is called a rainbow table.

For example, a lot of people use "password" and "john" as their passwords. In MD5, these two passwords always generate to: password: 5f4dcc3b5aa765d61d8327deb882cf99 john : 527bd5b5d689e2c32ae974c6229ff785

So if you just MD5 your passwords, and someone's naive enough to make that their password, it would probably be compromised if a hacker controlled your database and ran it against a rainbow table.

However, if you add some sort of gibberish to every pre-hashed value, like "password12345" and "johnxyz" then you get 2 entirely different hashes that would not be the same as those above. This is called a salt value, and it prevents rainbow tables from being as effective.

My recommendation would be to use the highest level of the SHA algorithms that you can in your programming language, and hash against a salt value (you can create a "random" one by hashing the current time if you like) that you store in the database record with the hashed password.

DB columns: Username | Password | Salt

This isn't the most secure system anyone's ever thought of, but it will likely work for yours.

Jordan
You could hash with the username as well, which will most likely be unique in a user database, i.e. a "random salt".
Patrick
Yup, pretty much anything you wanted would work if you didn't have any need for it to be truly random. There are of course random number generators that you could hash if you really cared too.
Jordan
+1 Though there are many ways a hash could become *"insecure"* in the eyes of the security community; that is just one of them. Whether the known vulnerabilities currently affect your application is beside the point: **Why use a theoretically insecure hash when using a theoretically secure one is just as easy?** Besides, better-safe-than-sorry because, as Bruce Schneier always says, *"Attacks only get better, never worse!"* :)
BlueRaja - Danny Pflughoeft