2011-11-11 79 views
3

我正在處理一個大項目的註冊系統。如何在生成註冊激活密鑰時防止衝突?

註冊成功後,服務器會生成一些激活密鑰,並將其添加到用戶的行並通過電子郵件發送給用戶。爲此使用一些密碼生成器類。

問題是(我知道它聽起來很抽象,但我只是想知道),如何避免重複傳代?我的意思是,在未來的生成器中是否有可能創建已經存在於db表中的激活密鑰?密鑰生成後我應該檢查重複嗎?

+0

產生除非你使用需要的Top500超級計算機,使一些關鍵瘋狂複雜的密鑰生成器,它應該瑣碎生成密鑰並檢查數據庫是否已經生成過。 –

+0

當然,您遲早會用完獨特的值,但這並不重要,因爲這些都是初始值和隨機值,因此非常安全。事實上,我們不能告訴你你的算法產生重複的可能性有多大,因爲我們根本不知道它。 - 如果你需要聲明一個值不重複,你可以測試它的唯一性,或使用一些隨機字符串加時間戳。 – Smamatti

回答

2

試用uniqid()

+0

uniqid是一個壞主意,因爲它根本不是隨機的,因此完全可以預測。 – NikiC

+3

如果您使用$ more_entropy參數,應該是一個非問題。 – simshaun

+0

Thx傢伙的幫助。這段代碼足夠安全嗎? md5(uniqid(mt_rand(),true)); –

0

你可以使用的時間,但它不會是「隨機」你不得不一些隨機性給它添加...

$key = md5(time()); 
+0

md5不是碰撞安全的,您的解決方案實際上會爲一些同時註冊生成相同的激活密鑰。 –

+0

還有一件事,這個關鍵md5(uniqid(mt_rand(),true));?我應該爲數據庫列選擇哪種類型和長度? –

+0

md5返回一個32長度的字符串,所以varchar(32)就是你需要的表列 –

3

我建議使用PEAR的Text_Password package。不要試圖重塑這個輪子。

請勿強制密碼嚴格唯一。它實際上是減去安全有執行。考慮如果我嘗試將密碼設置爲xyzzy並且網站告訴我我不能,那意味着現在我知道某些帳戶正在使用xyzzy作爲密碼。我只需在所有帳戶上嘗試使用該密碼,直到找到哪一個。

不要使用散列摘要作爲生成的密碼。您的用戶不想輸入32個字符(或更長)的十六進制字符串。我曾在2001年使用PKI和MD5哈希編碼安全軟件激活密鑰包的經驗。但沒有人會使用它,因爲鑰匙太長。

是否使用哈希摘要和鹽來存儲密碼。閱讀這篇由我們無畏的領導者撰寫的文章:You're Probably Storing Passwords Incorrectly

另見我的回答其他幾個密碼相關的問題:

+0

Thx快速回復,先生。這段代碼足夠安全嗎? md5(uniqid(mt_rand(),true)); –

+0

還有一件事,這個關鍵md5(uniqid(mt_rand(),true))會持續多久?我應該爲數據庫列選擇哪種類型和長度? –

+0

我錯過了什麼嗎?我不認爲他正在生成密碼。他正在生成激活密鑰。 (Text_Password仍然可以用於此目的。) – simshaun

1

使用哈希算法像SHA或惠而浦與一個獨特的輸入(如用戶的唯一用戶名)將導致一個預期的衝突率爲0的散列。

我不會推出我自己的算法。如上所述,uniqid()md5()是有保證的解決方案。

+0

哪個更好uniqid或md5? –

+0

此代碼是否足夠安全? md5(uniqid(mt_rand(),true)); –

+0

在您的PHP安裝範圍內'uniqid'可以保證生成一個唯一的id,因此理論上'uniqid'更好。但是,在實踐中,兩者可能大致相同。 *編輯*我會說代碼是「安全的」,但在這種情況下,安全性並不是真正的因素。它會產生一個獨特的結果,但它是如何使用它,使其安全。 – rockerest

0

使用GUID作爲註冊碼,因爲它始終是唯一的,並通過系統