2013-03-19 88 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哈希。