即使只有部分密码正确,也可以登录


Can login even if only the password is partially correct?

我偶然发现我的登录表单有问题。当密码部分正确时,我似乎可以登录。

如果我创建以下用户:

用户名:呵呵呵呵

密码:呵呵呵呵

我可以用"呵呵"、"呵呵"1111等密码登录。如果我写错了,它就不起作用了。

登录.php

if (empty($_POST) === false) {
$username = trim($_POST['username']);
$password = trim($_POST['password']);
if (empty($username) === true || empty($password) === true) {
    $errors[] = 'Sorry, but we need your username and password.';
} else if ($users->user_exists($username) === false) {
    $errors[] = 'Sorry that username doesn''t exists.';
// } else if ($users->email_confirmed($username) === false) {
    // $errors[] = 'Sorry, but you need to activate your account. 
                 // Please check your email.';
} else {
    if (strlen($password) > 18) {
        $errors[] = 'The password should be less than 18 characters, without spacing.';
    }
    $login = $users->login($username, $password);
    if ($login === false) {
        $errors[] = 'Sorry, that username/password is invalid';
    }else {
        $_SESSION['id'] =  $login;
        header('Location: home.php');
        exit();
    }
}

}

User.class.php

public function login($username, $password) {
    global $bcrypt;
    $query = $this->db->prepare("SELECT `password`, `user_id` FROM `users` WHERE `username` = ?");
    $query->bindValue(1, $username);
    try{
        $query->execute();
        $data               = $query->fetch();
        $stored_password    = $data['password']; 
        $id                 = $data['user_id']; 
        if($bcrypt->verify($password, $stored_password) === true){ 
            return $id;
        }else{
            return false;   
        }
    }catch(PDOException $e){
        die($e->getMessage());
    }
}

Bcrypt.class.php

class Bcrypt {
private $rounds;
public function __construct($rounds = 12) {
    if(CRYPT_BLOWFISH != 1) {
        throw new Exception("Bcrypt is not supported on this server, please see the following to learn more: http://php.net/crypt");
    }
    $this->rounds = $rounds;
}
private function genSalt() {
    $string = str_shuffle(mt_rand());
    $salt   = uniqid($string ,true);
    return $salt;
}

public function genHash($password) {
    $hash = crypt($password, '$2y$' . $this->rounds . '$' . $this->genSalt());
    return $hash;
}

public function verify($password, $existingHash) {
    $hash = crypt($password, $existingHash);

    if($hash === $existingHash) {
        return true;
    } else {
        return false;
    }
}

}

有什么想法吗?

如果你们认为这可能与注册过程有关,请告诉我,我也会上传注册代码。我不明白的是,为什么即使只是部分密码是正确的,它也能工作,我以前从未经历过这种情况。

crypt似乎使用DES进行哈希,而不是blowfish:http://php.net/manual/en/function.crypt.php

标准的基于DES的crypt()将salt作为输出的前两个字符返回。它也只使用str的前八个字符,因此以相同八个字符开头的较长字符串将生成相同的结果(当使用相同的salt时)。

尝试使用您的代码只使用前8个字符登录。

还要查看存储在数据库中的已保存哈希,看看它们是使用blowfish还是DES。如果使用河豚,它们应该有你使用的$2y$签名。

相关文章: