【发布时间】:2016-09-29 10:32:48
【问题描述】:
(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 将密码和盐值的哈希值存储在密码字段中。
现在我需要编写一个查询,当提供用户名和密码时,它会返回 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
我最终在第一步中针对用户名获取盐值,然后在 .NET 中以与上述 PHP 代码中完全相同的方式进行哈希处理,然后将其传递给 MySQL 以获取用户 ID。
【问题讨论】:
-
为什么不先计算哈希并在查询中使用它?
-
您“获取了一段代码”,却不知道它是如何处理安全存储密码的?这是非常不负责任的。
-
@SrinivasaReddy 什么?没有人会在用户表中保存盐。
-
@Justinas 你不知道加盐是干什么用的。将每个用户的 salt 存储在 users 表中就可以了。
-
@dotNET 安全的盐存储是您最不必担心的问题。使用真正的密码散列算法。 SHA 系列函数不适用于此目的。