Possible Duplicate:
Which password hashing method should I use?
There are a ton of great posts about password security in databases on stack overflow and on other sites and as I am completely new to this I spent quite some hours trying to learn more about it in the last days. However, there are so many different suggestions and best practices that I still got very confused...
Also, there are still many older posts from 2007-2010 etc I as I saw how fast things change I am not sure if this is still common to use it like they suggest. So, I wanted to summarize what I found in the posts and then ask if this method I found was a good practice...
So, this is not a guide, but a summary, I know it is very very basic and if there are mistakes please correct me!
- Just to mention: you should never store plain text passwords :)
- You "one-way" hash passwords, so nobody can ever see the plain text. When the user enters the password, you hash it the same way and compare it with the hashed pass in the database.
- In addition to hash a password, you should salt it. You add the salt to the plain password string and hash the new string. If the plain password is weak, adding the salt makes it longer and stronger.
- The salt should furthermore be random (I've read that the term "salt" means it is random anyway, otherwise it was called "key"?). This is to prevent rainbow table attacks, because the attacker would need to create one table for each salt which is much more expensive in terms of time etc. Also if two users have the same password you will not recognize it if you use random salts.
- The salt is not a secret! It is being stored in the database next to the hashed password. However, it may not be the best idea to use a timestamp, the user's e-mail address or anything else connected to the user as a random salt. As a reason it is e.g. mentioned that users tend to use the same passwords on multiple sites/services. So, the salt should be a random string, I've read best would be 64-bit?
- The next step is to add iteration to the hashing process (1000 or more loops), so the salt is added to the password and they are then hashed over and over, which means only a fraction of a second for the user to wait when logging in, but sums up if you have somewhat 10.000 entries in your DB.
- It might be a slight benefit, if you add a site key, stored e.g. as a global var in addition to the salt. However, you should always suppose that attackers have access to your file system as well.
- Hashing algorithms: I found for sure it is not secure anymore to use MD5, SHA1 and other weak methods...
So, there are different opinions on wether to use SHA256, SHA512? Should you use hash_hmac? Some say yes: (http://rdist.root.org/2009/10/29/stop-using-unsafe-keyed-hashes-use-hmac/) some say using libraries is the only secure way... and then once or twice in a post I've read not to use libraries as bcrypt or bubble fish??
Is it really necessary to use a library or is e.g. a method like this enough:
function hash_password($password, $nonce) {
for ($i = 0; $i < 5000; $i++) {
$hashed_pass = hash_hmac('sha512', $hashed_pass . $nonce . $password, $site_key);
}
return $hashed_pass;
}
Many people say don't invent your own algo, so I am a little bit scared just to use anything self-invented.
I can imagine it is hard to predict, but how long can a method used to today be considered as being secure enough?
UPDATE: So, thank you for all your great feedback. There is one main point missing, as I see and many of you said: password security, meaning a strong password is the basic. I think I got the message, thank you again! :)
UPDATE 2: Just for completion, I have found following code on http://www.lateralcode.com/creating-a-random-string-with-php/ that I use to generate a random salt:
function rand_string( $length ) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!§$%&/().-:;_#+*[]{}=";
$size = strlen( $chars );
for( $i = 0; $i < $length; $i++ ) {
$str .= $chars[ rand( 0, $size - 1 ) ];
}
return $str;
}
$random_salt= rand_string(20);