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?
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?
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 :)
storage is cheap and processors are fast. use a 1 kilobyte salt with SHA-512.
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.
MD5 and SHA1 are both considered insecure, with SHA-1 being better. However, there are 2 things that you should consider:
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.
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.