0

当用户尝试登录时,有两种方法可以检查用户是否有效。

方法一:执行如下查询,检查返回的行数是否为1。

SELECT * FROM users WHERE username = $_POST['username'] AND password = md5($_POST['password'])

方法二:执行查询,然后检查密码是否匹配。

SELECT * FROM users WHERE username = $_POST['username']

while ($row = mysqli_fetch_array($r, MYSQLI_ASSOC)){
   if($row['password'] == md5($_POST['password'])) $logged_in = TRUE;
}

这些方法中的一种是否优于另一种?如果是这样,为什么?

4

3 回答 3

4

使用密钥、盐和密码。md5不安全。

在服务器上,您存储一个密钥:

$key = 'fPu6AY;h0-5Q>cIel,@n2$gickGs9{ys~+DT,v|Mz-]~EU3tuj18|~Ch#1_$)fGR';

用户注册时会生成一个唯一的盐,并与加密密码一起存储在服务器上:

| 盐 | 密码 |
-------------------------------------------------- -------------------------------------------
| jAcTgi~4(Z | 877236d15a7b7a1f36febc49e58b142d70d72cf7d6e54dcfb252d7cde6b62a2d |

密码是这样加密的:

$hash = hash('sha256', $keyFromServer . $saltFromDb . $userPassword);

然后,您必须使用方法 2 来获取 salt 和 hash 以将其与数据库密码进行比较。

于 2013-03-19T20:39:06.240 回答
2

方法 2 是首选,因为您可以使用 PHPass 之类的库。它还使您能够告诉用户他们输入了无效的用户名,而不是让他们猜测他们是否输入了错误。Aarolama 关于 md5 不安全是正确的。不幸的是,SHA 系列也不是。这两者都是文件哈希,用于唯一标记和识别文件。使用加密哈希来保护密码,例如河豚。PHPass 为您处理了很多安全问题。盐应该是随机生成的,并且对于每个用户都是唯一的,而获得它们供自己使用的唯一方法是通过第二种方法。

于 2013-03-19T20:59:49.110 回答
0

要添加到FreshPrinceOfSO的答案,不要简单地将密钥与加盐的明文连接起来——而是使用 HMAC 方法:

$hash = hash_hmac('sha256', $saltFromDb . $userPassword, $keyFromServer);

可以在WikipediaRFC 2104中找到有关 HMAC 的更多详细信息,以及为什么这种简单方法存在缺陷的解释。还值得注意的是,与单独的底层哈希算法相比,HMAC 受冲突的影响要小得多,即尽管核心算法和输出大小相同,但它们更安全。

顺便说一下,关于输出大小。在上述 RFC 2104 的第 5 节中,指出截断散列(原始大小的一半或更大)在减少可能值的总数的同时,使通过蛮力恢复明文变得更加困难,如攻击者无法使用要检查的完整哈希值。这也适用于非 HMAC 哈希。

于 2013-04-05T17:15:52.037 回答