1

I have been trying to learn about hashes and salts stored in a users table withing a mysql DB. I get through with storing them but can't seem to wrap my head around how to validate when the user logs in.
I have looked through and seen about storing the salt and hash seperately and together. The salt that I am producing is random.

Any ideas?
I have posted my code.

<?php
$password = 'passwordwhatever';

//generate the salt
function gen_salt() {
    $salt = uniqid(mt_rand(), true) . sha1(uniqid(mt_rand(), true));
    $salt = crypt('sha512', $salt);
    return $salt;
}

//generate the hash
function gen_hash($salt, $password) {
    $hash = $salt . $password;
    for($i = 0; $i < 100000; $i++) {
        $hash = crypt('sha512', $hash);
    }

    $hash = $salt . $hash;
    return $hash;
}

$password = gen_hash(gen_salt(), $password);
echo $password;

?>
CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
Thom
  • 31
  • 1
  • 3
  • The salt generation can be done in a less overkill way though; just a `uniqid(mt_rand(), true)` is enough for that purpose and adding a `sha512` over that ain't going to make it more random ;-) – Ja͢ck Jun 05 '12 at 01:46

3 Answers3

2

As long as you produce the same salt, it shouldn't matter too much. Store it in your db, in configuration, as long as you can get to it. The effort of reversing a SHA512 hash is so high that unless you're the Pentagon, nobody will bother. The point is that you want to be able to repeat the hash with the same salt so you can be very sure that the input was the same without having to store the sensitive input. If that makes sense.

Jeff Watkins
  • 6,343
  • 16
  • 19
  • Right on the money. I was going to comment that you really don't need to go through much effort encrypting salts like that. The most important thing is that it's random, not that it's ultra secure. Even if someone gets the salt and hash, creating a rainbow table specifically for that salt is not a computationally practical effort. I wouldn't give it away willy-nilly (keep it in the back-end, don't disclose it to users publicly), but just coming up with a random string of letters and numbers is usually plenty secure enough. – King Skippus Jun 05 '12 at 00:54
  • Couple of side notes: 1) Don't use the same salt for every password; each salt should be unique per password. Not LITERALLY unique; you don't have to check that one doesn't exist or anything, just make them long enough so that practically speaking there's very little chance of duplicates. 2) Normally I store the salt with the hash using something like a colon as a delimiter. If you might want to hash other stuff using it, though, you can store it in its own column in the password table. – King Skippus Jun 05 '12 at 00:57
1

The salt is going to need to be contained somewhere within the database (or somewhere). Some options are to append the salt to the hash or stored as its own field. I like appending it to the hash.

$password = $salt . '.' . $hash;

Then when the user goes to login, you grab his password, break it into the hash and the salt, and use your password generation function (with the salt from the password instead of a random salt) to determine if it matches the password in the db.

list($salt,$hash) = explode('.', $password);
$check = gen_hash($salt, $input_pass);
if ($check === $password)
    // valid
None
  • 5,491
  • 1
  • 40
  • 51
0

Maybe you should take a look on bcrypt. This might help you. I wrote some tutorials but they are in german. Oh and PHP 5.3 support bcrypt natively.

Community
  • 1
  • 1
Oliver
  • 2,864
  • 1
  • 16
  • 27