我知道这个问题被问过这么多次,有很多关于这个主题的教程,但我无法解释我做错了什么。你能告诉我我的代码有什么问题吗?数据库连接正常工作,但我不知道问题出在哪里或者我是否理解错误,当我不对密码进行哈希并直接输入时没有问题。无论我输入什么,我的登录都不起作用并且总是返回“false”。
这是我的代码(注意,我有一个处理变量类型的自定义DBConnector类)
public function insertUser(){
if (isset($_POST['name']) && isset($_POST['password'])){
try
{
$name = $_POST['name'];
$password = $_POST['password'];
$db = CDatabase::getInstance();
//check if username is already in use
$db->prepare("SELECT * FROM user where LOWER(name) = LOWER(?)");
$db->bindParams(array($name));
$db->execute();
$result = $db->fetch();
//if no user with the same name was found
if ($result->num_rows == 0){
//insert user without password
$db->prepare("INSERT INTO user (name) VALUES(?)");
$db->bindParams(array($name));
$db->execute();
//get user_id of last inserted user because I use user_id as salt
//pls feel free to correct me if this is stupid
$user_id = $db->getLastInsertedId();
$salt = $user_id;
//hash password with user_id
$saltedHash = hash('sha256', $password, $salt);
var_dump($saltedHash);
//update user with password
$db->prepare("UPDATE user set password = ? where user_id = ?");
$db->bindParams(array($saltedHash, $user_id));
$db->execute();
//since I call this function via ajax true -> user is inserted correct
echo "true";
}else{
echo "Error: name is already in use";
}
}
catch(Exception $e)
{
$this->m_renderer->loadTemplate('error.html');
$this->m_renderer->assign(array('errorcode' => 6000, 'errormessage' => $e->getMessage()));
$this->m_renderer->render();
}
}
}
这是我的登录功能
public function loginUser(){
if (isset($_POST['name']) && isset($_POST['password'])){
try
{
$name = $_POST["name"];
$password = $_POST['password'];
$db = CDatabase::getInstance();
$db->prepare("SELECT * FROM user where LOWER(name) = LOWER(?)");
$db->bindParams(array($name));
$db->execute();
$result = $db->fetch();
if ($result->num_rows > 0){
$row = $result->fetch_assoc();
$salt = $row["user_id"]; //use user_id as salt
$saltedHash = $row["password"];
var_dump($password);
var_dump(hash('sha256', $password, $salt));
var_dump($saltedHash);
if (hash('sha256', $password, $salt) == $saltedHash) {
echo "correct";
} else {
echo 'Error: password incorrect';
}
}else{
echo "Error: username does not exist";
}
}
catch(Exception $e)
{
$this->m_renderer->loadTemplate('error.html');
$this->m_renderer->assign(array('errorcode' => 6000, 'errormessage' => $e->getMessage()));
$this->m_renderer->render();
}
}
}
这是我控制台的输出
string(32) "��Ё�L}e�/���Z���O+�,�]l�� //insertUser hash('sha256', $password, $salt);
"
true
string(4) "test"
string(32) "��Ё�L}e�/���Z���O+�,�]l�� //loginUser hash('sha256', $password, $salt)
"
string(31) "????L}e?/???Z???O+?,?]l?? //this value is in my database
"
Error: password incorrect
我在本地机器上使用最新版本的XAMPP
很多谢谢
答案 0 :(得分:1)
问题是hash()
返回二进制数据,你显然没有在数据库中处理/存储为二进制数据,这会破坏散列。
更大的问题是你首先使用的是hash()
。 甚至更大的问题是你错误地使用它。见其签名:
string hash ( string $algo , string $data [, bool $raw_output = false ] )
它无处接受盐。您设置为$salt
的内容实际上是$raw_output
,这就是您从中获取二进制数据的原因。
单个无盐的SHA-256回合也无法保证密码存储安全;你的散列密码是彩虹表攻击的主要部分,可能已存在于某处。
停止使用hash
,改为使用password_hash
和password_verify
。请参阅他们的示例,了解如何准确使用它们。