PHP/mySQL登录失败

PHP/mySQL登录失败,php,mysql,Php,Mysql,我已经编写了一个php用户登录脚本,虽然我已经设法让注册页面工作(从而排除了我的common.php文件的内容是一个问题),并在mySQL中检查了数据库正在填充,但我似乎无法让登录本身发布任何东西,除了不成功 我肯定是在数据库中输入了用户名和密码。有人能看到我哪里出了问题,或者建议我如何检查出了什么问题吗 jmp_users表的结构如下: jmp_userID / init(11) / auto_increment jmp_username / varchar(30) / utf8_unicod

我已经编写了一个php用户登录脚本,虽然我已经设法让注册页面工作(从而排除了我的common.php文件的内容是一个问题),并在mySQL中检查了数据库正在填充,但我似乎无法让登录本身发布任何东西,除了不成功

我肯定是在数据库中输入了用户名和密码。有人能看到我哪里出了问题,或者建议我如何检查出了什么问题吗

jmp_users表的结构如下:

jmp_userID / init(11) / auto_increment
jmp_username / varchar(30) / utf8_unicode_ci
jmp_password / varchar(40) / utf8_unicode_ci
salt / char(16) / utf8_unicode_ci
我的login.php页面是:

<?php 

require("common.php"); 

$submitted_username = ''; 

if(!empty($_POST)) 
{ 
    $query = " 
        SELECT 
            jmp_userID, 
            jmp_username, 
            jmp_password, 
            salt 
        FROM jmp_users 
        WHERE 
            jmp_username = :username 
    "; 
    $query_params = array( 
        ':username' => $_POST['jmp_username'] 
    ); 

    try 
    { 
        $stmt = $db->prepare($query); 
        $result = $stmt->execute($query_params); 
    } 
    catch(PDOException $ex) 
    {  
        die("Failed to run query: " . $ex->getMessage()); 
    }  
    $login_ok = false; 
    $row = $stmt->fetch(); 
    if($row) 
    { 
        $check_password = hash('sha256', $_POST['jmp_password'] . $row['salt']); 
        for($round = 0; $round < 65536; $round++) 
        { 
            $check_password = hash('sha256', $check_password . $row['salt']); 
        } 

        if($check_password === $row['jmp_password']) 
        { 
            $login_ok = true; 
        } 
    } 
    if($login_ok) 
    { 
        unset($row['salt']); 
        unset($row['jmp_password']); 
        $_SESSION['user'] = $row; 
        header("Location: private.php"); 
        die("Redirecting to: private.php"); 
    } 
    else 
    { 
        print("Login Failed."); 
        $submitted_username = htmlentities($_POST['jmp_username'], ENT_QUOTES, 'UTF-8'); 
    } 
} 

?> 
<h1>Login</h1> 
<form action="login.php" method="post"> 
    Username:<br /> 
    <input type="text" name="username" value="<?php echo $submitted_username; ?>" /> 
    <br /><br /> 
Password:<br /> 
<input type="password" name="password" value="" /> 
<br /><br /> 
<input type="submit" value="Login" /> 
</form> 
<a href="register.php">Register</a>

登录
用户名:

当您使用SHA256(使用十六进制值,而不是原始值)时,需要64个字符来存储密码的散列(您只有40个)

顺便说一句:我认为重新哈希密码65536次是不必要的和CPU浪费。
此外,通常所有密码都使用一个salt字符串。

在生成哈希时,逻辑有点扭曲。注册表表单是否也运行相同的哈希过程?顺便说一句,您可以使用内置的int-password\u-verify函数()。是的(据我所知)。我正在使用中的代码,但删除了电子邮件部分,因为它们对我的使用是不必要的。您的脚本是否输入
if($row)
部分???嗯,教程有点旧,特别是关于密码哈希的部分。您应该打印两个值-一个来自db,另一个由您计算。如果它们不匹配,您无法找到问题,我建议切换到password_verify,它更易于使用,而且可能更可靠。您是否将密码重新设置了60k次以上?多次哈希密码和使用多种盐对安全性更有利。是的,重新哈希的方法是从我构建此代码时遵循的代码中获得的。现在已经大大减少了。密码可用字符的#已被修复,用于测试的数据库条目已被替换,但仍然没有成功。我想我一直在学习一个过时的教程。“如果有人能给我指一个,我很乐意选择一个不太过时的。”米哈斯当然。但在不必要的高水平下,达到了65536倍。关于盐,如果你在五角大楼网站工作,你可以选择多种盐。但这里我们有一个主要缺陷:salt与散列密码一起存储。这很糟糕,因为任何破坏数据库的人都会看到salt和散列密码。盐必须留在其他地方,可能是代码。显然,如果客户机-服务器连接是通过https进行的,那么所有这些讨论都是有意义的,否则会有更大的漏洞,因为密码是通过网络发送的。如果有人获得了数据库,他也可以获得代码。若每个密码只有一个salt,那个么他将能够立即为每个流行问题计算哈希。@Michas若有人获得了数据库,他也可以获得代码。绝对不一定!!。数据库和应用程序甚至可以位于不同位置的不同计算机上。但如果有人得到了数据库,哈希和salt都在数据库中,salt就没用了。盐留在代码中;此外,多盐是无用的。