0

I'm a bit of a n00b in regards to hashing passwords, so go easy on me. Basically, I've put together some code that first of all sanitises the string's entered by the user on registration. Once that's done, a random salt is generated. The password is then appended to the salt:

  $salt = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));

    $saltedPW =  $p . $salt;

I then hash the password using a sha256 and go ahead and insert the user into the database, which all appears to be working correctly:

   $hashedPW = hash('sha256', $saltedPW);

    $q = "INSERT INTO user (id, name, email, password, verified, user_level, salt) VALUES
    (NULL, '$n', '$em', '$hashedPW', 'no', '1', '$salt')";

    $r = @mysqli_query ($dbc, $q); //run the query

Then, when it comes to the user logging in, I again sanitise the user-entered string, get the salt from the database assign it to a variable before appending the password to it as follows:

       $saltQuery = "SELECT salt FROM user WHERE email = '$email'";

        $result = mysqli_query($dbc, $saltQuery);

        $row = mysqli_fetch_assoc($result);

        $salt = $row['salt'];

        $saltedPW =  $password . $salt;

The salted password is then hashed using a sha256, as before, and I attempt to get the user information from the database:

    $hashedPW = hash('sha256', $saltedPW);

      $query = "SELECT * FROM user WHERE email = '$email' AND password = '$hashedPW'";

        $r = @mysqli_query ($dbc, $query);

However, the login fails, and when I print off the query I get the following result, when I presume the password should equal the user's entered string, which in this case is 'password' for testing purposes:

  SELECT * FROM user WHERE email = '[email protected]' AND password = '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8'

Is there anything you can see there that I'm doing wrong that would cause the login to fail? Thanks

1 Answer 1

2

SHA256 is a message digest, not a password hashing function, so you certainly should not be using it as such.

Cryptography is hard, and to do it well is even harder - it is for this reason that you should avoid rolling your own encryption functions and use ones that are tried and true, such as bcrypt or the newer scrypt.

PHP provides access to the bcrypt alogirthm through the password_hash function, which automatically generates a salt and encrypts the password using a much greater degree of security than SHA256. You would use it like so:

$hashedPassword = password_hash($password);

Then, when the user logs in, you would hash the password he inputted using the same function, and retrieve that user from the database.

Sign up to request clarification or add additional context in comments.

2 Comments

Per the PHP.net password hashing FAQ you would actually use password_verify() to verify the password, which will use the random salt that password_hash() generated and stored in its output. Please use as high a work factor ("cost" optional argument) as you can get away with during peak times. Note also that password_hash() and password_verify() are available in PHP 5.5, and in 5.3.7 with a compatibility library.
Thanks for that. Turned out I was using an old version of PHP, so didn't realise password_hash was an option. I've integrated that now, and it's much easier to implement. I'm

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.