2013-03-19 86 views
0

当用户尝试登录时,有两种方法检查用户是否有效。更好地检查用户名和密码或只是用户名?

方法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; 
} 

其中一种方法比其他方法更受欢迎吗?如果是的话,为什么?

回答

4

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

在服务器上,你存储的关键:

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

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

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

密码是这样加密的:

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

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

+0

但假设我使用密钥,散列和盐,方法1或方法2更可取? – Lars 2013-03-19 20:41:21

+0

您将需要使用方法2来获取盐。 – Kermit 2013-03-19 20:42:31

+0

但我仍然不能使用方法1,例如...“WHERE用户名= $ _POST ['用户名']和密码= hashed_salted_pa​​ssword($ _ POST ['password'])”,那个函数为我工作? – Lars 2013-03-19 20:45:19

2

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

0

为了增加FreshPrinceOfSO的回答,不要简单地连接具有咸明文密钥 - 使用HMAC方法来代替:

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

上HMAC更多细节可以在Wikipedia被发现RFC 2104,同时解释为什么这种琐碎的方法是有缺陷的。值得一提的是,HMAC的冲突影响明显小于单独的基础散列算法,即尽管核心算法和输出大小相同,但它们更安全。

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