大多數Web應用程式要求其用戶通過詢問用戶名和密碼來對自己進行身份驗證。他們將用戶提供的憑據與存儲在其資料庫中的數據進行比較,如果憑據匹配,則授予用戶訪問權限。聽起來不錯!但是,如果網站存儲密碼的資料庫遭到破壞,將會發生什麼?本文介紹了在資料庫中存儲密碼的各種技術。
大多數網站中有55%的網絡用戶使用相同的密碼!這意味著,如果以純文本形式存儲您的密碼的網站遭到破壞,黑客不僅可以訪問該網站上的帳戶,還可以訪問您使用相同密碼的所有社交媒體,電子郵件,論壇等帳戶!
好吧,許多人一定想知道,如果資料庫暴露給黑客,那該怎麼辦?黑客有權訪問所有信息。錯誤!有很多方法可以使黑客從資料庫中檢索密碼變得很麻煩。即使這樣,開發人員還是傾向於忽略基本準則,而是以純文本形式存儲密碼。有超過30%的網站以純文本形式存儲您的密碼(也包括一些知名網站)。如果網站以純文本形式存儲您的密碼,那麼無論您選擇多強的密碼,都不安全!
在資料庫中存儲純文本密碼是一種罪過:可能還會有人認為,如果不是純文本,那麼我們必須對密碼進行加密然後再存儲。這也是一個可怕的想法。加密功能提供輸入和輸出之間的一對一映射,並且它們始終是可逆的。如果黑客獲得了密鑰,他將能夠解密密碼。更好的方法是使用單向加密哈希函數。散列函數在輸入和輸出之間提供多對一映射,實際上不可能反轉輸出。好的加密哈希函數具有較少的衝突(即,對於函數的不同輸入值,很難獲得相同的輸出)。由於鴿洞原理,無法完全避免碰撞。對於哈希密碼,我們可以假設哈希函數將生成唯一的輸出,即對於沒有兩個不同的密碼,我們將獲得相同的哈希值。
一些流行的加密哈希函數是MD5和SHA1。代替將純文本密碼存儲在資料庫中,一種方法是存儲密碼的哈希。您可能會想,如果我們無法從哈希中找回實際密碼,那麼我們將如何驗證用戶輸入的憑據?很簡單,對用戶輸入的密碼應用相同的哈希函數,然後將其與資料庫中存儲的哈希進行比較。如果兩個哈希都匹配,則對用戶進行身份驗證(因為相同輸入的哈希將提供相同的輸出)。現在,如果攻擊者能夠訪問資料庫,則他將只能查看哈希輸出,而不能查看實際密碼。
使用加密哈希功能比存儲純文本密碼更好:黑客是聰明人,一旦他們知道開發人員正在存儲哈希密碼,便會預先計算大量單詞(從常用單詞列表或詞典單詞中)的哈希值。他們創建了一個單詞表及其相應的哈希表。該表被稱為Rainbow Table,可隨時在線獲得。他們可以使用此表通過比較從資料庫獲得的哈希值來反向查找實際密碼。因此,擁有一個強大的密碼非常重要,因為密碼出現在單詞列表中的可能性越來越小。
隨著GPU和CUDA,OpenCL庫的引入,處理能力大大提高。快速的GPU可以在一秒鐘內生成數百萬個MD5 / SHA1哈希。因此,黑客可以通過暴力破解各種可能的組合輕鬆地生成大量哈希,並將其與存儲在資料庫中的哈希進行比較以提取實際密碼。
甚至哈希密碼也不安全!驚訝嗎不要失去希望!開發人員仍然可以採取一些措施來防止您的密碼被黑客竊取。加入一些鹽使密碼更美味!鹽是隨機數據,在將其作為哈希函數的輸入發送之前,已與您的密碼連接在一起。例如:如果您的密碼是abc,鹽是!ZaP0#8,則hashFunction('abc!ZaP0#8')的結果將存儲在資料庫中,而不是hashFunction('abc')。因此,彩虹表攻擊現在將不再有效,因為彩虹表包含「 abc!ZaP0#8」散列的概率很小(因為通常彩虹表是由常用詞,字典詞等構成的)。鹽不存儲在資料庫中,而僅存在於外部用戶無法訪問的應用程式配置文件中。獲得對源文件的訪問比獲得對資料庫的訪問困難。上述加鹽方法是靜態的。我們為所有密碼設置了一個固定的位數。要驗證用戶身份,請先將固定鹽連接到用戶提供的輸入(密碼),然後將值傳遞給哈希函數,然後將其與資料庫中存儲的值進行比較。但是,這種方法仍然容易受到暴力攻擊,如果攻擊者能夠獲得靜態鹽,則可以通過將鹽串聯在每個單詞中來使用舊的攻擊方法。
更好的方法是使用動態鹽。對於每個用戶,加密強度高的隨機字符串生成器都會生成新的鹽。用戶輸入的密碼與隨機生成的鹽和靜態鹽串聯在一起。連接的字符串作為哈希函數的輸入傳遞。獲得的結果存儲在資料庫中。由於動態鹽對於不同用戶而言是不同的,因此需要將其存儲在資料庫中。當要驗證用戶身份時,首先從資料庫中獲取該用戶的動態鹽的值,然後將其與用戶提供的輸入和靜態鹽連接起來。將結果與存儲在資料庫中的哈希進行比較。
如果資料庫遭到入侵,黑客不僅會獲取您的密碼哈希,還會獲取所使用的動態鹽。您可能想知道,如果攻擊者擁有動態鹽,那麼動態鹽比靜態鹽有什麼優勢?即使攻擊者擁有動態鹽,他也需要為資料庫中存在的每個用戶(根據動態鹽)創建一個新的哈希表(或Rainbow表)。這比為所有用戶只創建一張表要昂貴得多。