使用salt验证用户的单个查询

时间:2013-05-02 23:51:10

标签: php mysql mysqli

我有一个包含3列的表:email,pass,salt

当用户登录时,我收到电子邮件并通过 - 但不是盐。如何通过单个查询验证用户?

这就是我要做的事情(但显然有缺陷):

$query = "SELECT users.salt FROM users WHERE email='$email' AND password='{hash_hmac('sha256', $password, users.salt)}'";

谢谢!

3 个答案:

答案 0 :(得分:3)

在您尝试使用它创建哈希时,您没有来自数据库的用户盐。

使用基于salt的哈希时,通常会从数据库中选择用户salt和密码(以及稍后可能需要的其他信息,如用户ID)。并在您的应用程序中进行哈希比较。

答案 1 :(得分:1)

您不能在大括号内使用函数:{hash_mac( ...

使用此:

$query  = "SELECT users.salt FROM users WHERE email='$email' AND password='";
$query .= hash_hmac('sha256', $password, users.salt) . "'";

但仍有问题。 PHP上下文中将不提供users.salt。你必须先得到它:

// get salt (pseudo code):
$salt = db_query("SELECT users.salt FROM users WHERE email = '$email'");

// use it in the query
$query  = "SELECT users.salt FROM users WHERE email='$email' AND password='";
$query .= hash_hmac('sha256', $password, $salt) . "'";

偏离主题:我发现这很有趣,这里有一个基本的例子,如何在花括号中使用一个函数。我在我的示例中使用rand()函数:

$rand = 'rand';
echo "{$rand()}";

答案 2 :(得分:0)

你在这里混合PHP和SQL的方式是无法完成的。

这是一种非常糟糕的方式:

SELECT * FROM users
  WHERE email=:email
    AND SHA2(CONCAT(:password, salt), 256)=:hashed

请注意,这将导致对数据库中所有用户记录进行行扫描,并且执行情况非常糟糕。这就是为什么这种方法从未在生产代码中使用的原因。

您应该做的是获取特定电子邮件的salt,使用它散列提供的密码,然后将结果与保存的散列值进行比较:

SELECT * FROM users WHERE email=:email

如果您使用库而不是编写自己的库,那么您可能不会遇到这些问题。至少你没有使用MD5。