PHP MySQL password hashing returns always false

Robin Schambach

I know this question is asked so many times and there are many tutorials about this thematic but I can't explain what I'm doing wrong. Could you pls tell me what is wrong in my code? The database connection works as it should, but I don't know where the problem is or if I understood something wrong, when I don't hash the password and entry it directly there is no problem. No matter what I entry my login will not work and always returns "false".

Here is my code (note, I have a custom DBConnector class that handles variable types)

    public function insertUser(){
        if (isset($_POST['name']) && isset($_POST['password'])){
            try
            {
                $name = $_POST['name'];
                $password = $_POST['password'];

                $db = CDatabase::getInstance();
                //check if username is already in use
                $db->prepare("SELECT * FROM user where LOWER(name) = LOWER(?)");
                $db->bindParams(array($name));
                $db->execute();

                $result = $db->fetch();
                //if no user with the same name was found
                if ($result->num_rows == 0){
                    //insert user without password
                    $db->prepare("INSERT INTO user (name) VALUES(?)");
                    $db->bindParams(array($name));
                    $db->execute();
                    //get user_id of last inserted user because I use user_id as salt
                    //pls feel free to correct me if this is stupid
                    $user_id = $db->getLastInsertedId();
                    $salt = $user_id; 
                    //hash password with user_id
                    $saltedHash = hash('sha256', $password, $salt);
                    var_dump($saltedHash);

                    //update user with password
                    $db->prepare("UPDATE user set password = ? where user_id = ?");
                    $db->bindParams(array($saltedHash, $user_id));
                    $db->execute();
                    //since I call this function via ajax true -> user is inserted correct
                    echo "true";
                }else{
                    echo "Error: name is already in use";
                }
            }   
            catch(Exception $e) 
            {
                $this->m_renderer->loadTemplate('error.html');
                $this->m_renderer->assign(array('errorcode' => 6000, 'errormessage' => $e->getMessage()));
                $this->m_renderer->render();
            }
        }
    }

And this is my login function

public function loginUser(){
        if (isset($_POST['name']) && isset($_POST['password'])){
            try
            {
                $name = $_POST["name"];
                $password = $_POST['password'];

                $db = CDatabase::getInstance();
                $db->prepare("SELECT * FROM user where LOWER(name) = LOWER(?)");
                $db->bindParams(array($name));
                $db->execute();

                $result = $db->fetch();
                if ($result->num_rows > 0){
                    $row = $result->fetch_assoc();
                    $salt = $row["user_id"];        //use user_id as salt
                    $saltedHash = $row["password"];

                    var_dump($password);
                    var_dump(hash('sha256', $password, $salt));
                    var_dump($saltedHash);
                    if (hash('sha256', $password, $salt) ==  $saltedHash) {
                        echo "correct";
                    } else {
                        echo 'Error: password incorrect';

                    }
                }else{
                    echo "Error: username does not exist";
                }
            }
            catch(Exception $e) 
            {
                $this->m_renderer->loadTemplate('error.html');
                $this->m_renderer->assign(array('errorcode' => 6000, 'errormessage' => $e->getMessage()));
                $this->m_renderer->render();
            }
        }
    }

And this is the output from my console

string(32) "��Ё�L}e�/���Z���O+�,�]l�� //insertUser hash('sha256', $password, $salt);
"
true
string(4) "test"
string(32) "��Ё�L}e�/���Z���O+�,�]l�� //loginUser hash('sha256', $password, $salt)
"
string(31) "????L}e?/???Z???O+?,?]l?? //this value is in my database
"
Error: password incorrect

I'm using the latest version of XAMPP on my local machine

Thank you very much

deceze

The problem is that hash() returns binary data, which you're apparently not handling/storing as binary data in the database, which corrupts the hash.

The bigger problem is that you're using hash() in the first place. The even bigger problem is that you're using it incorrectly. See its signature:

string hash ( string $algo , string $data [, bool $raw_output = false ] )

Nowhere does it accept a salt. What you set as $salt is actually $raw_output, which is why you're getting binary data from it.

A single unsalted SHA-256 round is also nowhere close to being secure for password storage; your hashed passwords are prime for a rainbow table attack, which probably already exists somewhere.

Stop using hash, use password_hash and password_verify instead. See their examples for how to use them exactly.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related