PHP自帶的MD5和SHA1加密函數是否安全,看了不少年前的一篇博文。原文爲英文,我的英語能力真的有限,翻譯了一下,其中一定存在不少錯誤,但願各位能夠指正。
原文連接web
中國最大的開發者社區網站CSDN被破解了,數據庫泄露。在泄露的數據庫中,密碼是明文存儲的。人們在微博上發表關於密碼和安全相關的消息。我注意到一條消息,用MD5/SHA1+salt存儲密碼並不安全。該條微博的做者強烈建議使用BCrypt進行加密。雖然我不擅長的加密和安全技術,可是在個人記憶中,SHA1+salt是存儲密碼最流行的方式。怎麼多是不安全的?數據庫
我爲密碼安全定義了兩個級別:黃色級別和紅色級別。當數據庫被泄露,若是經過計算獲得一個能夠經過認證的密碼,這時安全級別爲黃色;若是經過計算能夠獲得原始密碼,這時安全級別爲紅色。緩存
紅色級別的安全隱患比黃色級別嚴重不少。人們一般在不一樣的站點使用相同的密碼。若是原始密碼被泄露,全部的站點都存在安全隱患。若是攻擊者不能計算出原始密碼,那麼影響的僅僅是被攻擊的站點。在個人印象中,人們須要防範紅色級別的安全隱患。防止黃色級別並非硬性要求。安全
在個人印象中,hash+salt已經足夠好了。爲何我還要使用BCrypt?服務器
若是咱們分析定義的兩個級別,咱們應該提出這樣的問題:對於給定的經過計算獲得的密碼,如何判斷它是不是原來的。常見的解決方案是使用數據字典或分析字面模式。當涉及到數據字典時,它將變得頗有趣。攻擊者一般使用暴力破解和數據字典兩種方式進行密碼破解。從維基百科和BCrypt的介紹來看,hash+48bit salt很難被暴力破解。這須要半分鐘來遍歷全部的6個字符的密碼。對於48位散列,須要花費幾個月時間。函數
在這種狀況下,攻擊者一般選擇放棄,除非目標用戶是一個重要人物。當暴力破解失敗,惟一的辦法就是使用數據字典。若是密碼不在數據字典中,那麼你將無能爲力。性能
以上的分析基於salt不被泄露的狀況。若是salt被泄漏,我的用戶失去保護。在這種狀況下,攻擊者只需進行逐一計算。攻擊者不能使用rainbowmap。若是密碼複雜程度爲8位字符,須要超過70小時,遍歷全部的可能性。網站
從上面的分析,使用hash+salt不一樣狀況下有不一樣結果:加密
BCrypt犧牲性能來獲得安全。它計算出hash比hash+salt要慢10000倍,所以增長了10000倍的破解成本。翻譯
對於BCrypt,若是salt被泄露,一個簡單的密碼破解成本也須要幾天。若是使用簡單密碼,用BCrypt進行加密也是不安全的。但若是salt沒有丟失,或者salt丟失可是密碼很複雜,須要不少年才能達到黃色級別,而且不可能獲得紅色級別。
做爲總結,用戶不要使用過於簡單的密碼。
使用hash+salt加密的狀況下,若是你的密碼夠複雜,不須要擔憂你會變成紅色級別。惟一的例外是,你是攻擊者的暗戀對象、傷了攻擊者心的好基友,那麼你將成爲攻擊者的目標,他不惜耗費大量時間來破解你的密碼。
使用Bcrypt加密的狀況下,你老是安全的,除非你使用過於簡單的密碼。然而,因爲Bcrypt性能的緣由,若是你須要使用Bcrypt,那麼你須要購買更多的web服務器用來密碼驗證。若是你有2個驗證服務器,如今,你須要購買20000個服務器!
固然你能夠配置BCrypt,使其更快,可是安全性將會降低。或者,你能夠緩存明文密碼,並在內存中計算出的哈希值,但若是內存轉儲泄漏,全部的明文密碼將被泄露。
綜上所述,若是你採用如下建議,建議使用hash+salt進行加密:
單獨存放hash和salt。
強制用戶使用強密碼。
設計本身的哈希函數。不要簡單地複製粘貼常見開源代碼。