Search code examples
phpmysqlsalt-cryptographysha256password-hash

sha256/salt password key storage


I have created a registration form processed as follows:

function register_user() {
   global $conn;
   $name      = sanitize($_POST['name']);
   $email     = sanitize($_POST['email']);
   $password = sanitize($_POST['password']);
   $salt      = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));

   $saltedPW = $password . $salt;
   $hashedPW = hash('sha256', $saltedPW);

   mysqli_query($conn, "INSERT INTO users (name, email, password, salt) VALUES ('$name', '$email', '$hashedPW', '$salt')");

The login form is then processed as follows:

    function login($email, $password) {
    global $conn;
    $user_id = user_id_from_username($email);
    $query   = mysqli_query($conn, "SELECT salt FROM users WHERE email = '$email'");
    $row1    = mysqli_fetch_assoc($query);
    $salt    = $row1['salt'];

    $saltedPW = $password . $salt;
    $hashedPW = hash('sha256', $saltedPW);

    $result = mysqli_query($conn, "SELECT COUNT(user_id) FROM users WHERE email = '$email' AND password = '$hashedPW'");
    $row     = mysqli_fetch_row($result);

    return ($row[0] == 1) ? $user_id : false;
}

The user table is structured as follows: user_id; name; email; password; salt (additional columns for password recovering, admin rights, etc.). Having submitted the details to my company's IT compliance department, someone with PHP experience (exceeding mine no doubt) has stated that I can't store the key for the encryption in the system - if someone got the file they could decrypt the password. My question is - is this correct? Is my process flawed? All of the research I have carried out indicates that an SHA256 hash with random salt is one of the best ways to go.


Solution

  • I can't store the key for the encryption in the system

    You haven't. You're hashing, you're not encrypting. salt !== key

    if someone got the file they could decrypt the password

    No. Nothing is encrypted, so there's nothing to decrypt. They'd get only the resulting hash, which they'd still have to brute force.

    Is my process flawed?

    Yes, but not because of their comments. It's flawed because you should never use SHA or MD5 or similar for passwords. They're designed to be fast, which is not what you want. You want something that intentionally takes a hunk of CPU, as to make brute force attacks untimely. This is exactly what the password_hash() function is for. Use it.