在查询

时间:2016-05-31 12:03:03

标签: php mysql sql hash

(PHP和MySQL不是我的专业领域,所以这可能是一个简单的单线程。)

我只是从互联网上抓取了一段执行用户注册的代码。除此之外,它使用以下行来记录密码:

$salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647)); 
$password = hash('sha256', $_POST['password'] . $salt); 
for($round = 0; $round < 65536; $round++){ $password = hash('sha256', $password . $salt); }

如果我理解正确,则使用SHA-256在密码字段中存储密码和salt值的哈希值。

现在我需要编写一个查询,当提供用户名和密码时,返回UserID值。阅读MySQL手册,看起来没有SHA-256的内置函数(支持旧的SHA和MD5)。或者情况不是这样吗?

SELECT 
     id 
FROM 
     users 
WHERE 
     (username = @UN) 
     AND (password = SHA256(CONCAT(@PWD, salt)))

这显然不起作用,因为没有定义SHA256。

修改

刚刚发现MySQL 5.5.5中有SHA2可以执行SHA-256:

SELECT 
     id 
FROM  
     users 
WHERE 
     username = @UN 
     AND password = SHA2(CONCAT(@PWD, salt), 256)

但这也不会返回任何行。也许我没有完全按照上面的注册页面做的事情。

编辑2

我可能不够清楚。我从.NET查询数据库,而不是PHP。我包含的PHP代码只是为了展示它是如何存储在第一位的。这意味着我必须依赖MySQL的功能进行散列,或者在.NET中执行它,如果MySQL无法在查询中执行此操作。

编辑3

我在第一步中最终获取了对用户名的salt值,然后在.NET中进行散列,与上面的PHP代码完全相同,然后将其传递给MySQL以获取用户ID。

2 个答案:

答案 0 :(得分:2)

确认电子邮件和密码时,您通过电子邮件请求用户

SELECT * FROM users WHERE username = :username;

并且将数据库密码与传递的密码进行比较:

if ($db->password == $this->hash($_POST['password'])) {
    //Match
} else {
    //Does not match
}

或者你可以从PHP端传递哈希到MySql:

SELECT id FROM users WHERE username = :username AND password = :passwordHash

最佳将使用PHP函数password_hash(),它将为您生成盐并使密码类似$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
要验证密码,只需拨打password_verify($_POST['password'], $dbPasswordHash)

More about passwords

答案 1 :(得分:0)

一般例外的做法是在应用程序代码中从用户提供的密码生成哈希值,然后检查该哈希值与存储在数据库中的哈希值。

此外,php已经内置了处理这个功能的功能,而且它们几乎肯定会比一些自制选项设计得更好,特别是你在没有完全理解的情况下复制的选项。

最初保存密码:

$hashed = password_hash($_POST['password']);
DB::insert('users',['email'=>$email, 'password'=>$hashed]);

登录时检查:

$user = DB::select('users',['email=?', $_POST['email']]);
if($user && password_verify($_POST['password'], $user['password'])){
   //good to go
}

http://php.net/manual/en/function.password-hash.php

http://php.net/manual/en/function.password-verify.php

根据您的评论编辑,如果您需要在.NET应用程序中修改密码,以下SO答案可能会有用:

looking for c# equivalent of php's password-verify()