簡體   English   中英

你如何在MySQL中安全地存儲用戶的密碼和鹽?

[英]How do you securely store a user's password and salt in MySQL?

所以,我發現你應該將密碼與“鹽”一起散列。 (文章可以在這里這里找到。)

這是代碼:

$password = 'fish';

/* should be "unique" for every user? */
$salt= 'ABC09';

$site_key = 'static_site_key';

hash_hmac('sha1', $password . $salt, $site_key);

現在我需要在MySQL中保存$password$salt ,如下所示:

+---------+--------+----------+-------+
| user_id |  name  | password |  salt |
+---------+--------+----------+-------+
|    1    | krysis |  fish**  | ABC09 |
+---------+--------+----------+-------+

** fish當然會被散列,而不是以純文本形式存儲。

而我只是想知道這樣做是否真的有意義,因為這樣一個黑客或誰也知道鹽? 所以,如果他們破解密碼並看到它的fishABC09他們會自動知道密碼是fish嗎? 或者他可能“永遠”無法破解密碼,因為他不知道secret_key ,因為它沒有存儲在數據庫中?

如果我沒有任何意義,我很抱歉。 我只是總是使用sha1作為密碼,今天我發現這些文章談到了添加salt

關於正確存儲密碼的文章很好。 其中一個例如: 存儲密碼 - 完成正確!

您應該為每個用戶使用不同的鹽,但不需要單獨存儲鹽。 另一個線程中查看類似的討論

順便說一句,你可能不應該使用sha1但是例如sha256或sha512更強的東西(至少為了避免不良宣傳)。 對此有一個很好的答案: 鹽漬SHA1與鹽漬SHA512相比有多不安全

$username = mysql_real_escape_string($username);
$password = mysql_real_escape_string($password);
$time = time();
$query = "
INSERT INTO user (name, unixcreationtime, passhash) 
VALUES ('$username', '$time', SHA2(CONCAT('$time','$password'),512) ";

不要使用SHA1,它不再安全。
我建議在MySQL中進行所有哈希,這樣你就可以確定哈希的結果沒有區別。

使用以下選擇用戶:

$query = "SELECT id FROM user 
          WHERE name = '$username' 
            AND passhash = SHA2(CONCAT(creationdate,'$password'),512) ";

彩虹/字典攻擊和鹽漬密碼 - 異端方法

密碼不應存儲在您的數據庫中。 不要推出自己的身份驗證機制 - 你幾乎肯定會弄錯。 使用Kereberos作為有價值的東西,而且我沒有其他好的建議。

然而,這個問題一直在我的頭骨中徘徊一段時間(見編輯),我想提出一個異端的觀點。

彩虹表是所謂的,因為查找機制(鏈接)的使用方式 - 但它們只是字典攻擊。 數以百萬計的字典單詞和常用密碼被預先散列,然后用於比較被盜的散列密碼。

這適用於使用md5哈希和無鹽的NT4密碼進程。 但是當在散列之前將鹽添加到密碼中時,彩虹表是無用的 - 而不是尋找“mypass”的md5散列,它必須預先計算“mypass-random-string_of-letters”

不可能猜到有人會使用什么樣的鹽,因此鹽漬使彩虹表成為通用,可以在任何地方使用任何服務器解決方案。

但......

這只是一個用例 - 當然是一個很大的威脅,肯定是一個防御。 但鹽有問題。 當您想要在下次用戶登錄時進行身份驗證時,您必須保留鹽。他們發送明文(通過ssl!),將salt和hash,comapre附加到存儲在數據庫中的哈希。 但是,如果你不保留鹽密碼,你不能這樣做,並且錯誤...沒有登錄

但是我們不僅要防止人們繞過一張桌子來破解NT4密碼。 我們應該單獨保護我們的用戶。

鹽為密碼添加了雙因素防御 - 即使使用哈希,攻擊者也需要鹽才有機會破解密碼。 但標准建議只是放棄了兩個因素防御。 可能是合理的,但我不相信。

這背后有一些數學。 通常的建議(由RSA提供 - ftp.rsa.com/pub/pkcs/pkcs-5v2/pkcs5v2-0.pdf)構建一個64位的鹽,用散列密碼存儲它。 這樣,您可以通過與salt重新進行重新確認密碼,並且幾乎不可能反轉哈希值。

NB - 我在這里錯了......

“接下來不可能”的位來自簡單的數學。

讓我們假設一個8位數的密碼,有62個可能的字符(字母,大寫字母和數字)

這是62 ^ 8組合,或略多於2億萬億。

通過直接計算哈希值(即制作我的鹽特定彩虹表)來強制執行此操作,我應該在62 ^ 8/2之后看到碰撞,並且在每秒100次哈希時,它將花費大約1200萬天。 是的幾天。

好吧,所以即使用密碼存儲哈希也會使查找哈希的任務變得不可行。

但是,上面有一些假設。 首先,密碼是62 ^ 8范圍的隨機選擇。 在實踐中,大多數密碼都要弱得多 - 彩虹表並不是真正基於所有62 ^ 8種可能性 - 它們是由字典構建的,並且是多年來發現的真實密碼表。

所以搜索空間,而不是62 ^ 8真的更小。 多么小 ? 這取決於密碼“強度”。

英語大約有250,000 - 750,000個單詞(http://oxforddictionaries.com/page/93)。 讓我們把500,000作為一個簡單的案例。 然后我們可以采用可以應用的變體 - 添加數字,添加一年,將元音轉換為數字。 這讓我們說每個單詞有3個可能的新單詞,或者200萬個可能的密碼。

以100 /秒產生200萬個哈希值可提供20,000秒或5小時 - 完全在任何筆記本電腦的范圍內。

因此,如果有特定用戶被定位(root,admin,spolsky等),那么使用密碼立即存儲salt會使破解成為可能。

將鹽從密碼中存儲起來會增加破解的難度 - 不是以任何數學方式,只是難以獲得鹽和密碼。 可以設想一個單獨的服務器,只需要明文,用戶名和哈希,並查找用戶加入日期使用的鹽,並返回1/0

因此,簡而言之,如果您使用密碼存儲salt並且有人訪問密碼,那么根據密碼強度,每個密碼在合理的時間內都是可破解的。 每個用戶使用不同的鹽可以保護所有其他用戶,但如果您使用的是特定帳戶,則無關緊要。 如果黑客只使用一個密碼,那么使用密碼存儲鹽會使裂縫成為可能。 在密碼表的其他地方保留一個旋轉的鹽意味着黑客現在需要兩次數據竊取來破解密碼,因為沒有鹽,任何攻擊注定要經過數千年的工作。

這完全是一種折衷 - 迫使人們使用15位密碼意味着他們都會在屏幕上注明它,或者變得“容易記住”即單詞。

此時您也可以轉移到Kerberos或類似的 - 如果您保護的數據很有價值,用戶將理解並查看它。 如果不是我們為什么要打擾。

不過我還是建議你不要實現自己的身份驗證mechansim。 使用Kerberos,使用半公共PKI,不要自己滾動。 我不知道如何判斷我的服務器是否只是將持有我的鹽的RAM換成了磁盤,這只是我在編寫自己的身份驗證時可以立即想到的一個錯誤。

HTH

不,因為當密碼被哈希時它看起來不像fishABC09 ,它看起來像: 5f4dcc3b5aa765d61d8327deb882cf99這是一個md5哈希。

要獲得對系統的訪問權限,即使他們知道哈希值,也無法撤消。 我們使用salt來增加哈希的復雜性,並防止在彩虹表中進行哈希查找。

例如: Google搜索 “密碼”的md5哈希值為: 5f4dcc3b5aa765d61d8327deb882cf99

很多結果對嗎?

現在我要再次創建一個哈希,我仍然會使用“密碼”,但我會添加一個SALT,即“AHG(* @”。我猜這個帖子和一些僵屍刀具的唯一響應是已經閱讀過這篇文章:)

cbe57e92ffbb0086320891b9f979156d

應該只有幾個結果 ,或者這篇帖子都是這篇帖子。

只記得

請記住這個...哈希是一種方式 ,所以即使你獲得哈希,你也不知道用它來創建它

我知道這是舊的,但對於那些設法偶然發現這篇文章的人來說......

你真正想做什么HMAC。 試圖自己創造問題。 例如,您可以部分計算哈希值,從而減少猜測密碼所需的工作量。 HMAC解決了這些問題。

更好的是scrypt或bcrypt。 HMAC仍然經常使用設計為快速且易於計算的哈希算法; 甚至有許多哈希算法的硬件實現。 bcrypt計算量很大,scrypt是內存密集型的。 兩者都使攻擊者更難,但特別是scrypt使得構建硬件設備以破解密碼變得非常困難。

我真的很喜歡這里的圖表: https//github.com/pbhogan/scrypt#why-you-should-use-scrypt

這是一個古老的話題,但其他人也會來到這里,所以我會試着很容易地描述它:

如果你做哈希(密碼)你得到每個密碼相同的哈希值[哈希(密碼)=哈希(密碼)]。 如果兩個用戶擁有相同的密碼,您將看到它,因為哈希值是相同的。 一些密碼如“密碼”或“12345678”經常使用:數據庫中的相同哈希值 - >可能是密碼“password”或“12345678”(rainbowtable attack)。

如果你哈希(鹽+密碼)你沒有得到相同的密碼相同的哈希,因為哈希(salt1 +密碼)不是哈希(salt2 +密碼)。

hash(x)只是一個像f(x)= y的數學函數。 如果你把相同的x,你會得到相同的y。 這個功能必須“特殊”才能安全。 只是不要使用sha1,因為它不再安全:D

鹽是固定長度的隨機數。 對於每個存儲的條目,此鹽必須不同。 它必須以散列密碼旁邊的明文形式存儲。

https://www.owasp.org/index.php/Hashing_Java#Why_add_salt_.3F

如果黑客可以訪問您的PHP文件,他只需添加郵件功能,無論誰登錄,帳戶詳細信息都會通過電子郵件發送給黑客。

如果黑客只能訪問數據庫,他不應該在那里明確地寫入密碼,所以在保存之前將其加密。 將其保存在無法反轉的md5哈希中。

我通常使用基於username或userID的salt,PHP程序知道如何為每個用戶生成static_site_key。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM