2013-06-21 26 views
0

如何最好地使用確認碼對電子郵件通知的加密方法:MD5,SHA1或SHA256如何最好地使用確認代碼的加密方法

我做電子郵件通知確認一些行動通過電子郵件;

我用鹽和一些參數生成確認碼。

如何最好地使用加密方法確認代碼?

+1

請參閱此鏈接 - http://stackoverflow.com/questions/2593807/md5uniqid-makes-sense-for-random-unique-tokens – ejo

+0

安全性取決於您使用哪些輸入來生成散列,例如如果你使用'REMOTE_ADDR',那麼任何人都可以猜到它。 – DevZer0

回答

2

您這裏有兩個主要的選項:

  1. 產生一些隨機數據,其存儲在與該配置文件,相關數據庫,並把該鏈接僅此數據;
  2. 產生某種基礎上,也就是說,用戶ID安全散列,然後同時通過用戶ID和散列鏈接

第一個選項是安全的(假設你使用的是一個真正的隨機數發生器或非常非常好的僞隨機數發生器),但是您必須將數據存儲在數據庫中。

我通常更喜歡第二個選項,因爲不需要在數據庫中存儲任何內容,也不需要查詢數據庫來檢查鏈接是否有效。

選擇一個只有你的服務器知道的祕密密鑰,然後準確地定義你想在URL中驗證哪些參數(例如,只有用戶ID可能夠用;但是如果你想鏈接過期,你可以添加一個時間戳到URL並驗證用戶ID和時間戳與您的散列)。將您的密鑰與參數混合,基於此生成一個哈希,並創建一個指定您的參數和哈希的鏈接。當用戶點擊鏈接時,您從url中獲取參數,再次將它們與祕密密鑰相結合,對結果進行散列並與網址附帶的散列進行比較。

一種安全的方式來做到這一點是使用HMAC,這是基於散列的消息認證碼。參見:http://php.net/manual/en/function.hash-hmac.php

請注意,此機制會公開您在網址中驗證的數據。如果數據是祕密的(例如,假設您希望發送鏈接給包含用戶名和密碼的用戶,並且在點擊鏈接之前不在數據庫中保存任何內容),則必須使用Authenticated Encryption,這是一種混合的加密算法(保證沒有人可以讀取數據)和一個驗證算法(它保證沒有人可以用加密數據來產生有意義的東西 - 只有你的服務器能夠產生這樣的代碼)。

+0

正如你的回答正確地解釋的那樣,第二種方法需要仔細計劃,並且容易出錯(因爲複雜性是安全的敵人)。它提出了是否值得所有努力的問題,特別是在考慮到大多數用戶已經擁有某種數據庫的網站時。該數據庫可以用於第一種方法。 – ntoskrnl

+0

HMAC不是單面加密嗎?我如何將它解碼爲純字符串? – Volatil3

+0

HMAC不是一種加密算法,它是一種MAC算法。您不要「將其解碼爲純字符串」,這就是MAC算法的本質。另外,我不確定你的意思是「單面加密」*。 –

0

如果你只是生成一個「隨機」確認碼,你不必擔心你正在使用的哈希函數;您並不真正關心散列信息的安全性,只是在確認代碼的不可猜測性中。這意味着熵的位越多,確認碼的安全性(和唯一性)就越高。 MD5產生128位熵,SHA1位爲160位,SHA256位爲256位。使用大鹽(> = 1024位應該沒問題),並稱它爲好。

如果你希望它是真正安全的,然後讀ñ字節(其中ñ是一些大的數量,24+)從/dev/random/dev/urandom(前者只如果你運行像EGD,否則您可能容易遭受DOS攻擊)並以十六進制或64進制編碼,將它們存儲在您的用戶記錄中,並將其設置爲您的確認碼。這完全消除了猜測性,並沒有像普通辣椒那樣的單一攻擊點。

+0

我是否還需要使用salt和其他參數,或者您可以使用md5(uniqid(rand(),true))? – frops

+1

使用散列函數根本不會增加數據的熵 - 它只是將它擴展到特定的長度。你應該從安全的隨機數發生器中讀取字節。看到這個:http://stackoverflow.com/questions/1182584/secure-random-number-generation-in-php – ntoskrnl

+0

所以,我必須生成一個隨機序列的字符? – frops