我在登录表单上偶然发现了问题。当密码部分正确时,我似乎能够登录。
如果我创建以下用户:
用户名:hehehehehe
密码:呵呵呵呵呵
我可以使用“hehehehe”,“hehehehehe11111”等密码登录。如果我写错了,它就行不通。
的login.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;
}
}
}
有什么想法吗?
如果你们认为它可以处理注册过程,请告诉我,我也会上传注册码。我无法弄清楚的是,即使密码的一部分是正确的,为什么它仍然有效,我以前从未体验过。
答案 0 :(得分:1)
似乎地穴使用DES进行哈希而不是河豚: http://php.net/manual/en/function.crypt.php
标准的基于DES的crypt()返回salt作为输出的前两个字符。它也只使用str的前八个字符,所以较长的字符串以相同的八个字符开头将产生相同的结果(当使用相同的盐时)。
尝试使用您的代码仅使用前8个字符登录。
另请查看存储在数据库中的已保存哈希值,以查看它们是否正在使用blowfish或DES。如果使用河豚,他们应该使用$ 2y $签名。