0

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

如果我创建以下用户:

用户名:嘿嘿嘿嘿

密码:嘿嘿嘿嘿

我可以使用“hehehehe”、“hehehehehehe11111”等密码登录。如果我写的完全错误,它就不起作用。

登录.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();
    }
}

}

用户类.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;
    }
}

}

有任何想法吗?

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

4

1 回答 1

1

似乎 crypt 使用 DES 进行散列而不是河豚: http: //php.net/manual/en/function.crypt.php

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

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

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

于 2013-08-03T15:57:12.987 回答