我有一个包含3列的表:email、pass、salt
当用户登录时,我会收到电子邮件并通过,但不会收到盐。如何通过单个查询验证用户?
这就是我试图做的(但显然有缺陷(:
$query = "SELECT users.salt FROM users WHERE email='$email' AND password='{hash_hmac('sha256', $password, users.salt)}'";
谢谢!
在尝试使用数据库创建哈希时,用户不会从数据库中获得salt。
当使用基于salt的哈希时,通常会从DB中选择用户salt和密码(以及以后可能需要的其他信息,如用户ID(。并在应用程序中进行哈希比较。
不能在大括号内使用函数:{hash_mac( ...
使用此:
$query = "SELECT users.salt FROM users WHERE email='$email' AND password='";
$query .= hash_hmac('sha256', $password, users.salt) . "'";
但仍然存在一个问题。users.salt
在PHP上下文中将不可用。你必须先拿到它:
// 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()}";
您在这里混合了PHP和SQL,这是无法做到的。
这是一种非常糟糕的方式:
SELECT * FROM users
WHERE email=:email
AND SHA2(CONCAT(:password, salt), 256)=:hashed
请注意,这将导致对数据库中的所有用户记录进行行扫描,并且执行情况非常糟糕。这就是为什么这种方法从未在生产代码中使用过。
你应该做的是获取特定电子邮件的salt,用它对提供的密码进行散列,然后将结果与保存的散列值进行比较:
SELECT * FROM users WHERE email=:email
如果你使用图书馆而不是自己写,你可能不会有这些问题。至少你没有使用MD5。