最好检查用户名和密码或只是用户名?

时间:2013-03-19 20:37:21

标签: login passwords while-loop username

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

方法1:执行以下查询并检查返回的行数是否与1相同。

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

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

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

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

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

3 个答案:

答案 0 :(得分:4)

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

在服务器上,存储密钥:

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

当用户注册时会生成唯一 salt,并将其与加密密码一起存储在服务器上:

|       SALT |                                                         PASSWORD |
---------------------------------------------------------------------------------
| jAcTgi~4(Z | 877236d15a7b7a1f36febc49e58b142d70d72cf7d6e54dcfb252d7cde6b62a2d |

密码加密如下:

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

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

答案 1 :(得分:2)

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

答案 2 :(得分:0)

要添加到 FreshPrinceOfSO 的答案,不要简单地将密钥与salted明文连接起来 - 改为使用HMAC方法:

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

关于HMAC的更多详细信息可以在WikipediaRFC 2104中找到,同时解释为什么琐碎的方法存在缺陷。值得注意的是,与单独的基础哈希算法相比,HMAC受冲突的影响要小得多,即。即尽管核心算法和输出大小相同,它们仍然更安全。

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