-->

Using PHPass to hash password trouble

2019-07-30 16:12发布

问题:

I am using PHPASS to store password encrypted and compare when login.

here is the code

ob_start();
$userName = $password = "";
$userNameErr = $passwordErr = $loginErr = "";
$hasher = new PasswordHash(8, false);

if (isset($_POST['subEmployee'])) {
    if (empty($_POST['user_name'])) {
        $userNameErr = "User name is required";

    } else {
        $userName = check_input($_POST['user_name']);
        if (!preg_match("/^[0-9_a-zA-Z]*$/", $userName)) {
            $userNameErr = "Only letters, numbers and '_' allowed";
        }
    }
    if (empty($_POST['password'])) {
        $passwordErr = "Password is required";
    }else{
        $password = check_input($_POST['password']);
    }

    $active = 1;
    $loginUser = $db->prepare("SELECT password FROM users WHERE user_name=? AND activity=?");
    $loginUser->bind_param('si', $userName, $active);
    if ($loginUser->execute()) {
        $results = $loginUser->get_result();
        if ($results->num_rows == 1) {
            $row = $results->fetch_object();
            $stored_hash = "*";
            $stored_hash = $row->password;
            $check = $hasher->CheckPassword($password, $stored_hash);
            if ($check) {
                $_SESSION['name'] = $row->first_name;
                $_SESSION['userId'] = $row->id;
                $_SESSION['user'] = 1;
                print_r($_SESSION);
                header("Location:?pid=4");
            } elseif (!empty($_POST['user_name']) && !empty($_POST['password'])) {
                $loginErr = "'Invalid Login Information'";
            }
        }
    }
}

so far it always give the same message 'Invalid Login Information' I have made the registration form that store my password like this.

$hasher = new PasswordHash(8, false);
$hash = md5(rand(0, 1000));

if (empty($_POST['password'])) {
        $error ['passwordErr'] = "Password is required";
    } elseif (strlen($_POST['password']) < 8) {
        $error ['passwordErr'] = "<span class='notAllowed'>Chose password with at last eight characters</span>";
    } elseif (strlen($_POST['password']) > 72) {
        $error ['passwordErr'] = "<span class='notAllowed'>Password max 72 characters</span>";
    } elseif ($_POST['password'] !== $_POST['confirm']) {
        $error ['passwordErr'] = "Password don't matching";
    } else {
        $password = $hasher->HashPassword($password);
    }

when I checked my database the password seems hashed to me and the user name is there and everything is alright

but still getting this message as 'Invalid Login Information'.

does this two lines is right

$loginUser = $db->prepare("SELECT password FROM users WHERE user_name=? AND activity=?");
    $loginUser->bind_param('si', $userName, $active);

does the login code OK.

I try this too

Update I updated my code

if (isset($_POST['subEmployee'])) {
    $error=array();

    $hash_cost_log2 = 8;
    $hash_portable = FALSE;
    $hasher = new PasswordHash($hash_cost_log2, $hash_portable);

    if (empty($_POST['user_name'])) {
        $userNameErr = "User name is required";

    } else {
        $userName = check_input($_POST['user_name']);
        if (!preg_match("/^[0-9_a-zA-Z]*$/", $userName)) {
            $userNameErr = "Only letters, numbers and '_' allowed";
        }
    }
    if (empty($_POST['password'])) {
        $passwordErr = "Password is required";
    } else {
        $password = $_POST['password'];
    }
    $active = 1;

    $loginUser = $db->prepare("SELECT password FROM hired_person_info WHERE user_name=? AND activity=?");
    $loginUser->bind_param('si', $userName, $active);
    if ($loginUser->execute()) {
        $results = $loginUser->get_result();
        if ($results->num_rows == 1) {
            $row = $results->fetch_object();
            $stored_hash = "*";
            $stored_hash = $row->password;
            $check = $hasher->CheckPassword($password, $stored_hash);
            if ($check) {
                $_SESSION['name'] = $row->first_name;
                $_SESSION['userId'] = $row->id;
                $_SESSION['user'] = 1;
                print_r($_SESSION);
                header("Location:?pid=4");
            } elseif (!empty($_POST['user_name']) && !empty($_POST['password'])) {
                $loginErr = "'Invalid Login Information'";
            }
        } else {
            $loginErr = "'We didn't find any users'";
        }
    }
}

add this from the manual of PHPass

$hash_cost_log2 = 8;
        $hash_portable = FALSE;
        $hasher = new PasswordHash($hash_cost_log2, $hash_portable);

still no luck can somebody tell me where am mistaking here

Edit this is my check_input() code

function check_input($data) {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
}

and I am using PHP 5.3.29

Thanks

回答1:

These are some points i would check:

1) In your registration handler you check directly the POST variable, but for hashing you take a variable $password, i would access the input always in the same way, for example:

$password = $hasher->HashPassword($_POST['password']);

2) The function check_input() is not recommended for passwords, since you calculate a hash-value and this hash-value is "safe" anyway. Even for other user input, one should validate it as you did, but escaping should be done as late as possible, and only for the particular output. So the function htmlspecialchars() should not be called for user input, but always before outputting to HTML.

3) In your login handler you access the password once with the POST variable and once with the variable $password. The variable $password is set only in an if statement, so if the input is empty you fill the error but you continue with an uninitialized $password variable. Either fill the variable just at the beginning, or always use the POST variable.

4) Since you are using PHP 5.3.29 you can use the new function password_hash() with the compatibility pack. I do not think that the PHPass library is the problem here, nevertheless here is an example for the new function.

// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);

// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

5) Another often made mistake is, that the database field for storing the hash-value is too short, it needs a length of varchar(60). Maybe you could provide one of your password-hashes (of course only an example)?



回答2:

This library requires PHP >= 5.3.7 OR a version that has the $2y fix backported into it (such as RedHat provides).