简体   繁体   中英

What;s wrong with code which is getting user by email and checking for the password?

I 'm newbie to php and I 'm implementing a login system where user enters email and password and check for their existence in database (mysql in phpmyadmin)

the password is encrypted using this function when user first registers :

/**
 * Encrypting password
 *
 * @param
 *          password
 *          returns salt and encrypted password
 */
public function hashSSHA($password) {
    $salt = sha1 ( rand () );
    $salt = substr ( $salt, 0, 10 );
    $encrypted = base64_encode ( sha1 ( $password . $salt, true ) . $salt );
    $hash = array (
            "salt" => $salt,
            "encrypted" => $encrypted 
    );
    return $hash;
}

the salt parameter which is the key to decrypt the password is stored in the database with user's info and the decrypt code is :

/**
 * Decrypting password
 *
 * @param
 *          salt, password
 *          returns hash string
 */
public function checkhashSSHA($salt, $password) {
    $hash = base64_encode ( sha1 ( $password . $salt, true ) . $salt );

    return $hash;
}

the password is decrypted when i go and fetch the user with the email and password entered.

/**
 * Get user by email and password
 */
public function getUserByEmailAndPassword($email, $password) {
    $stmt = $this->conn->prepare ( "SELECT * FROM users WHERE email = ?" );

    $stmt->bind_param ( "s", $email );

    if ($stmt->execute ()) {
        $user = $stmt->get_result ()->fetch_assoc ();
        $stmt->close ();
        $salt = $user ["salt"];
        $hash = $this->checkhashSSHA ( $salt, $user ["encrypted_password"] );
        if ($hash == $password) {
            return $user;
        } else {
            return NULL;
        }
    } else {
        return NULL;
    }
}

the problem is when user enters correct email and password still this code returns NULL and i suspect something wrong with handling the password part.

Siguza's answer is correct, but your comment to his answer reflects a very reasonable confusion, because the name of the checkhashSSHA() function is a bit misleading (ie its name does not match its behaviour). A function name that start with "check" should be returning a boolean. I suggest changing it to:

/**
 * Decrypting password
 *
 * @param
 *          password, hash, salt
 *          returns boolean
 */
public function checkhashSSHA($password, $hash, $salt) {
    $hash2 = base64_encode ( sha1 ( $password . $salt, true ) . $salt );

    return ($hash == $hash2) ;
}

Now change these two lines:

$hash = $this->checkhashSSHA ( $salt, $user ["encrypted_password"] );
if ($hash == $password) {

to this one line:

if (checkhashSSHA($password, $user["encrypted_password"], $salt)) {

Now it's clearer and easier to use, and its behaviour matches its name. However, if you care to enhance the naming in your code, here are some suggestions:

  • Change checkhashSSHA() to compareHashSSHA() .
  • Change encrypted_password in the database to hashed_password .

More importantly, the sha1 hashing algorithm is a bit old and not very secure. I recommend changing it to a more secure hashing like sha512. Check this and read the comment from Kai Petzke for the full story.

The problem lies in these two lines:

$hash = $this->checkhashSSHA ( $salt, $user ["encrypted_password"] );
if ($hash == $password) {

First, you're hashing the already hashed password, instead of the plaintext password.
Then you're comparing that "hash of a hash" to the plaintext password.
So you're doing hash(hash(pw)) == pw , when it should be hash(pw) == hash(pw) .

You simply have to exchange $user ["encrypted_password"] and $password :

$hash = $this->checkhashSSHA ( $salt, $password );
if ($hash == $user ["encrypted_password"]) {

I would suggest instead of using the sshhash function you look into the php function password_verify()

Check the docs on that and related functions here: http://php.net/manual/en/function.password-verify.php

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM