2013-08-03 35 views
0

我acciedentley偶然發現我的登錄表單有問題。我似乎可以在密碼部分正確時登錄。即使只有密碼部分正確,也可以登錄嗎?

如果我創建以下用戶:

用戶名:hehehehehe

密碼:hehehehehe

我可以像 「呵呵呵呵」, 「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; 
    } 
} 

}

任何想法?

如果你們認爲這可能與註冊過程做,請讓我知道,我會上傳註冊碼以及。我無法弄清楚的是,即使只有部分密碼是正確的,爲什麼它能正常工作,我以前從未遇到過這種情況。

回答

1

看來隱窩使用DES用在哈希而非河豚: http://php.net/manual/en/function.crypt.php

的標準的基於DES-隱窩()返回鹽作爲輸出的前兩個字符。它也只使用str的前八個字符,所以以相同的八個字符開頭的較長的字符串將生成相同的結果(當使用相同的鹽時)。

嘗試與只使用你的代碼的前8個字符登錄。

也看看存儲在數據庫中,看看他們是否正在使用河豚或DES保存的哈希值。如果使用河豚,他們應該有你使用的$ 2y $簽名。

+0

fleed - 這似乎是這個問題,是的。例如,只要我超過8個密碼,我就會登錄。例如,我的數據庫中的哈希看起來很好。 「$ 2hk6fF3VetiQ」。 –

+0

@CheesePuffs - 這個存儲的散列值不會顯得很好。一個正確的BCrypt值將以'$ 2y $'開頭,註冊過程中肯定有錯誤。如果成本參數小於10,那麼您的類「Bcrypt」也會因爲格式化而失敗。我建議使用新的PHP函數[password_hash()](http://www.php.net/manual/en/ function.password-hash.php)或其兼容包。 – martinstoeckli

相關問題