2011-10-26 53 views
1

首先,我的加密和散列的理解:加密電子郵件,散列密碼並將它們存儲在數據庫中?

  1. 加密 - 可以解密
  2. 散列 - 不能被散列的

在構建Web應用程序,我應該:

  1. 使用加密密鑰加密電子郵件地址(將用於登錄)。很高興能夠解密電子郵件地址供以後使用(例如,向用戶發送電子郵件)
  2. 用鹽散列密碼。沒有人應該能夠看到用戶的密碼,所以哈希(因爲它是單向的)是好的。

如果上述2點是正確的,我應該在哪裏存儲加密密鑰和鹽?

如果我將它存儲在數據庫中,DB應該被破壞似乎有點沒有意義。但是,好處是我可以爲每個用戶分配一個唯一的加密密鑰和salt。

我應該在我的應用程序的配置中存儲加密密鑰和salt嗎?如果數據庫受到威脅,至少加密密鑰和鹽不會受到影響(希望)。問題在於,這可能意味着每個人都共享相同的加密密鑰和鹽。

建議怎麼做?

+0

也許你應該試着問在http://security.stackexchange.com/這種過度的一些偏執的意見。 – deceze

回答

1

如果你根本不加密電子郵件,你需要用一個普通的salt/key來完成。否則,你將如何通過他的電子郵件地址從數據庫中選擇一個用戶來檢查散列密碼是否正確?您無法每次解密每個電子郵件地址。

總的來說,我認爲從加密電子郵件地址中獲得的東西很少。如果需要,可以使用MySQL數據庫加密,但不要在應用程序級別擔心。

散列密碼的salt應該/必須是唯一的,並且可以存儲在數據庫中,實際上它可以是散列本身的一部分。請參閱http://www.openwall.com/phpass/以獲得良好實施。

+0

電子郵件加密不一定要使用共同的鹽/密鑰。重要的是,當涉及到解密時間時,你知道鹽/密鑰是什麼。加密的電子郵件地址,您可以暴露你的數據庫不會影響人的電子郵件地址,就像什麼,所以做的:http://data.stackexchange.com/stackoverflow/query/new – StackOverflowNewbie

+0

好了,你有一堆僞隨機的斑點你的數據庫中有噪音。用戶'foo @ example.com'想要登錄。你是做什麼的?當然,有辦法做到這一點,比如使用電子郵件地址本身作爲自己的關鍵,但它的複雜性更小,收益甚微。以SO的方式公開數據庫並不意味着電子郵件地址是加密的,它只是意味着它沒有暴露在公共接口中。 – deceze

+0

數據庫受損時是否有增益?如果電子郵件地址本身是加密的,會不會更好? – StackOverflowNewbie

0

鹽應該是每個用戶,並且可以確實在數據庫中;因此鹽的一點是有一個你的數據庫副本的人不能一次破解所有的密碼,但每個人都分開。

至於加密密鑰,這是一個更難的問題 - 絕對不要將其存儲在數據庫中;如果您的平臺提供任何類型的受保護存儲,則可能需要使用該存儲。見例如這個有用的答案:What's the best method to use/store encryption keys in MySQL

2

你的理解對我來說似乎是正確的。

密碼:只有密碼的散列應與用戶特定鹽一起存儲。鹽可以以明文形式存儲,鹽的原因是,攻擊者不能爲所有用戶使用一個單一的彩虹表(建立彩虹表價格昂貴)。建議使用hash_hmac()函數。

電子郵件:我認爲加密這些地址是個好主意,但是如果攻擊者能夠控制服務器,那麼他將能夠恢復這些地址。我會將一個祕密密鑰放在一個單獨的目錄中,該目錄位於Web根目錄之外(無法直接從Web訪問)。不要將它寫入可以不經解釋即可交付的文件中,擴展名* .php比* .inc更好。如果你無法訪問這樣的目錄,至少可以使用.htaccess Deny from all來保護它。

如果你需要找到在數據庫中,你還可以存儲哈希的電子郵件地址,這使得搜索不區分大小寫(先來小寫,然後生成散列)。

+0

您可以詳細解釋「如果您需要在數據庫中查找電子郵件地址,您可以額外存儲散列」? – StackOverflowNewbie

+0

也許用戶必須輸入電子郵件和密碼登錄,然後您的應用程序必須找到用戶。要找到用戶,您需要在數據庫中搜索此特定電子郵件地址。您可以在搜索之前加密電子郵件,但它會區分大小寫。 – martinstoeckli

相關問題