2010-08-20 184 views
5

我有一個登錄服務到我目前的網站,我想知道的是 - 是否有任何特定的方法,你可以稱之爲最安全?PHP/MySQL安全登錄和會話

讓我解釋一下我的系統好一點:

我現在有一個用戶表中的PHP MySQL數據庫。用戶名和密碼都存儲爲VARCHAR(不是我所知道的最好的密碼)。

在註冊表單方面,我通過僅允許a-Z 0-9條目並限制字符數來規定密碼和用戶名的選擇。在登錄表單一側,我通過使用mysql_real_escape_string來停止攻擊,並使用POST來代替AJAX的iFrame。

我覺得我正在盡我所能來防止來自Form側的攻擊,但不能從數據庫端進行攻擊。我知道你可以在進入數據庫時​​改變密碼存儲的類型來進行加密,但是我不明白的是如何查詢這個加密的字符串。

鑑於我所描述的,你會建議如何增加安全性,爲什麼?你選擇什麼方法來防止黑客攻擊?你能看到我所描述的任何明顯的安全漏洞嗎?也許最重要的是,考慮到我從未參與過網絡遊戲開發並且沒有太多經驗,我該怎麼做才能糾正這些問題?

(記住,我不會創建一個系統,以容納機密或炎症數據)

+1

最安全的方式是SSL +個人證書。雖然我懷疑你的網站確實需要最安全的網站。 – 2010-08-20 08:59:33

+2

另一件要提及的事情。一個聰明的SOer說,安全不是可以被添加的東西。這不是一件事,它是一個過程。 – 2010-08-20 09:02:40

+0

但是,即使是任何過程都可以細分爲一系列操作說明。這將是系統完成時的一個過程。 – 2010-08-20 09:11:14

回答

5

首先,不要明文密碼存儲在數據庫中。因此,註冊新用戶時,請將其密碼輸入爲hash。 MD5最常用於此。我建議用這個鹽。因此,對於存儲:

$password = md5($yoursalt . $_POST['password']); 

現在,當用戶想要登錄,您再次在您的文章有自己的密碼。現在製作和以前一樣的散列,然後在數據庫中搜索這個散列(用他們的用戶名)。這樣你就不會存儲他們的實際密碼。

+2

+1決定使用哪一個用於「至少使用散列和鹽」,-1用於「使用MD5" 。現在是2010年,密碼哈希的MD5是死的。請至少使用一種SHA-2功能。 – Piskvor 2010-08-20 09:43:52

+0

謝謝,這已經是一個很大的幫助。我的思考過程在用戶輸入密碼並從數據庫獲得加密密碼後停止,因此我沒有真正想到加密輸入的密碼並進行比較。謝謝 – 2010-08-20 09:46:01

+0

另外,'$ yoursalt'應該是每個用戶,而不是每個站點;這在你的回答中沒有明確提及。 – Piskvor 2010-08-20 10:07:25

3

將密碼散列到MD5或SHA1是網絡安全的重要組成部分。然後匹配密碼的方法是首先使用提供的用戶名從數據庫中檢索哈希密碼,對用戶提供的密碼進行哈希處理,然後匹配兩個哈希值。由於MD5和SHA1是單向哈希值,這意味着如果用戶丟失了密碼,則無法檢索當前密碼。新密碼需要重新創建。你可以通過使用PHP mcrypt()函數來解決這個問題。

您還應該允許在密碼中使用特殊字符。這隻會增加暴力攻擊的複雜性。

您也可以在3次錯誤嘗試後鎖定一段時間的帳戶,甚至在10次嘗試後鎖定IP地址。儘管後者屬於「焦油坑」類別。只是讓黑客更加困難一點。

+0

謝謝。我正試圖使用​​一些加密,正如我在上面的答案中所說的,我的想法並沒有延伸到加密輸入的密碼和比較:(謝謝你的答案非常清楚,許多人只會拋出很多的行話我的方式,並沒有經驗(我只有22)它不會是最好的學習方法 – 2010-08-20 09:50:08

+0

密碼是密碼是非常危險的,因爲它是可逆的..沒有密碼保護方法應該是可逆的 – MRW 2010-08-23 14:02:32

1

生成密碼時,我總是用一個用戶特定的鹽,所以我的「用戶」表有兩個字段「encrypted_salt」和「密碼」

頂部和它的底部是我SHA1(encrypted_salt +「密碼「);

當生成encrypted_salt時,我會使用sha1(unqid(true));它可以產生幾乎100%的獨特的鹽,因爲它使用時間以毫秒爲單位,並有額外的熵(鹽)。獲得重複的可能性幾乎爲0。

所以:

$salt = sha1(unqid(true)); 
$password = sha1($_POST['password']); 

在數據庫存儲中:

$pw = sha1($salt.$password); or sha1($password.$salt); 

它並不真正的問題。

SHA1的美妙之處在於它總能生成40個字符的字符串。你可以越吃越好,特別是如果你可以爲每個密碼生成一個獨特的鹽。

+0

我認爲基礎加密版本的用戶名+加密版本,你是否也會認爲這是可行的? – 2010-08-20 10:14:33

+0

是的,因爲用戶的id(pc)應該始終是唯一的,作爲一種最佳實踐,我總是使用某種時間戳在哈希中,所以您可以使用microtime(true)或time()或unqid()作爲2個用戶在完全相同毫秒內添加的可能性,尤其是因爲PHP不處理多線程。但是username.id會很好,尤其是散列。 – MRW 2010-08-20 10:18:07

+0

使用散列法,我認爲sha1 vs md5是個人偏好。我總是使用sha1(),但md5也一樣好! – MRW 2010-08-20 10:19:06

1

就你的SQL而言,不要使用類似mysql_real_escape_string的字符串轉換函數,它仍然可以允許在某些情況下發生注入攻擊。使用參數化查詢,從而確保數據庫在所有情況下將所有用戶提供的字符串視爲數據,而不是SQL代碼片段。

PHP中的MySQLi和PDO庫都支持參數化查詢。

+0

謝謝,我將如何將這些庫實現到我的代碼中?我將如何執行參數化查詢? – 2010-08-20 12:00:22

+0

這裏有大量的文檔和教程。這裏有一個http://forum.codecall.net/php-tutorials/12442-php-5-mysqli-prepared-statements.html – Cheekysoft 2010-08-23 09:32:44