I want to store a (random) salt next to the password in the database. Now, the question is:
Should I store it hashed or in plain text? Is there any difference (more security, faster?)? An how much effort should I put in creating a random string?
Sample code:
//Creating random salt
$saltchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&()*+,-./:;<=>?@[]^_`{|}~";
$salt = uniqid(rand(), true).str_shuffle($saltchars);
// Or should the salt be hashed (md5 or sha512 for more security)
// $salt = hash('sha512', uniqid(rand(), true).$staticsalt.str_shuffle($saltchars));
//Create user (with salt & pepper)
$sqlquery = "INSERT INTO users (user, password, salt) VALUES('$id','".hash('sha512', $staticsalt.$accesskey.$salt)."','".$salt."');";
$sqlresult = mysql_query($sqlquery);
for the record: the login-script
$sqlquery = "SELECT salt FROM users WHERE user='$id';";
$sqlresult = mysql_query($sqlquery);
if (mysql_num_rows($sqlresult) == 1) {
$salt = (mysql_fetch_array($sqlresult));
//Check if the password is correct
$sqlquery = "SELECT * FROM users WHERE user='$id' AND password='".hash('sha512', $staticsalt.$accesskey.$salt[0])."'";
$sqlresult = mysql_query($sqlquery);
unset($accesskey, $salt);
//Check whether the query w开发者_Python百科as successful or not
if($sqlresult) {
if(mysql_num_rows($sqlresult) == 1)
{echo 'Login successfull';}
else {die('Error: wrong user ID/password');}
}
}
I know that there are many, probably too many, websites out there discussing the pros & cons of a salt. But nobody answers if the salt should be encrypt or not - and nobody shows how to code a login script with random (!) salts (saved in the database as I did).
So as a php beginner I have no idea if this code is secure or not? Or if there are any tricks to make it faster or more streamlined... Thanks!
It doesn't matter. You can assume the salt is public information, since the attack the salt helps protect against -- rainbow-table assisted dictionary attacks -- isn't made any easier if the salt is known by the attacker. You should ask yourself why you think it's a good idea to encrypt the salt in the first place.
Also, you should read this:
- http://codahale.com/how-to-safely-store-a-password/
Since you need the salt to compute a password hash in the login script, you can't just store the hash of the salt as this would be an irreversible operation, i.e. the original salt would be lost.
So I'm presuming you're asking whether hashing the original salt obtained from picking a random string yields a better salt. In this case the use of a hashing function has nothing to do with 'hashing', it would just be a way to generate a longer, seemingly more random sequence. This makes absolutely no sense, however, as the hashed salt will still need to be stored in the database - in plaintext if you will!
Nobody talks about the salt being hashed because the salt can't be hashed. If it's not obvious why - and if you truly "have no idea if this code is secure or not" - please use somebody else's authentication system instead of creating your own, because it is very, very easy to leave gaping security holes if you don't know what you are doing.
Edit:
A hash is one-way. You put data in. You don't take data out. That's what it's for. If you put the salt in, you can't get it out. If you can't get it out, you can't add it to the password the user supplies. If you can't do that, you can't use it as a salt.
The purpose of the salt is so that someone can't use the same rainbow tables for cracking all the passwords. To create a new rainbow table for each password just makes the method too inefficient. You don't have to hide the salt, hiding it doesn't increase the security.
As the salt isn't a cryptographic key, and it doesn't have to be hidden, you don't have to be very elaborate when creating them. Just use a regular random generator to pick some random characters.
Besides, you can't hash the salt anyway, because then you can't use it to check the passwords when someone want to log in.
精彩评论