常見的使用者密碼加密方式以及破解方法

csdn發表於2017-08-27

  【作者】張輝,就職於攜程技術中心資訊保安部,負責安全產品的設計與研發。

  作為網際網路公司的資訊保安從業人員經常要處理撞庫掃號事件,產生撞庫掃號的根本原因是一些企業發生了資訊洩露事件,且這些洩露資料未加密或者加密方式比較弱,導致黑客可以還原出原始的使用者密碼。目前已經曝光的資訊洩露事件至少上百起,其中包括多家一線網際網路公司,洩露總資料超過10億條。

  要完全防止資訊洩露是非常困難的事情,除了防止黑客外,還要防止內部人員洩密。但如果採用合適的演算法去加密使用者密碼,即使資訊洩露出去,黑客也無法還原出原始的密碼(或者還原的代價非常大)。也就是說我們可以將工作重點從防止洩露轉換到防止黑客還原出資料。下面我們將分別介紹使用者密碼的加密方式以及主要的破解方法。

 一、使用者密碼加密

  使用者密碼儲存到資料庫時,常見的加密方式有哪些,我們該採用什麼方式來保護使用者的密碼呢?以下幾種方式是常見的密碼儲存方式:

  1、直接明文儲存,比如使用者設定的密碼是“123456”,直接將“123456”儲存在資料庫中,這種是最簡單的儲存方式,也是最不安全的方式。但實際上不少網際網路公司,都可能採取的是這種方式。

  2、使用對稱加密演算法來儲存,比如3DES、AES等演算法,使用這種方式加密是可以通過解密來還原出原始密碼的,當然前提條件是需要獲取到金鑰。不過既然大量的使用者資訊已經洩露了,金鑰很可能也會洩露,當然可以將一般資料和金鑰分開儲存、分開管理,但要完全保護好金鑰也是一件非常複雜的事情,所以這種方式並不是很好的方式。

  3、使用MD5、SHA1等單向HASH演算法保護密碼,使用這些演算法後,無法通過計算還原出原始密碼,而且實現比較簡單,因此很多網際網路公司都採用這種方式儲存使用者密碼,曾經這種方式也是比較安全的方式,但隨著彩虹表技術的興起,可以建立彩虹表進行查表破解,目前這種方式已經很不安全了。

  4、特殊的單向HASH演算法,由於單向HASH演算法在保護密碼方面不再安全,於是有些公司在單向HASH演算法基礎上進行了加鹽、多次HASH等擴充套件,這些方式可以在一定程度上增加破解難度,對於加了“固定鹽”的HASH演算法,需要保護“鹽”不能洩露,這就會遇到“保護對稱金鑰”一樣的問題,一旦“鹽”洩露,根據“鹽”重新建立彩虹表可以進行破解,對於多次HASH,也只是增加了破解的時間,並沒有本質上的提升。

  5、PBKDF2演算法,該演算法原理大致相當於在HASH演算法基礎上增加隨機鹽,並進行多次HASH運算,隨機鹽使得彩虹表的建表難度大幅增加,而多次HASH也使得建表和破解的難度都大幅增加。使用PBKDF2演算法時,HASH演算法一般選用sha1或者sha256,隨機鹽的長度一般不能少於8位元組,HASH次數至少也要1000次,這樣安全性才足夠高。一次密碼驗證過程進行1000次HASH運算,對伺服器來說可能只需要1ms,但對於破解者來說計算成本增加了1000倍,而至少8位元組隨機鹽,更是把建表難度提升了N個數量級,使得大批量的破解密碼幾乎不可行,該演算法也是美國國家標準與技術研究院推薦使用的演算法。

  6、bcrypt、scrypt等演算法,這兩種演算法也可以有效抵禦彩虹表,使用這兩種演算法時也需要指定相應的引數,使破解難度增加。

  下表對比了各個演算法的特性:

 二、使用者密碼破解

  使用者密碼破解需要針對具體的加密方式來實施,如果使用對稱加密,並且演算法足夠安全(比如AES),必須獲取到金鑰才能解密,沒有其它可行的破解方式。

  如果採用HASH演算法(包括特殊HASH),一般使用彩虹表的方式來破解,彩虹表的原理是什麼呢?我們先來了解下如何進行HASH碰撞。單向HASH演算法由於不能進行解密運算,只能通過建表、查表的方式進行碰撞,即將常用的密碼及其對應的HASH值全計算出來並儲存,當獲取到HASH值是,直接查表獲取原始密碼,假設用MD5演算法來保護6位數字密碼,可以建如下表:

  全表共100W條記錄,因為資料量不大,這種情況建表、查表都非常容易。但是當密碼並不是6位純數字密碼,而是數字、大小寫字母結合的10位密碼時,建立一個這樣的表需要(26+26+10)^ 10 ≈ 83億億(條記錄),儲存在硬碟上至少要佔用2000W TB的空間,這麼大的儲存空間,成本太大,幾乎不可行。有什麼辦法可以減少儲存空間?一種方法是“預計算雜湊鏈”,“預計算雜湊鏈”可以大幅減少HASH表的儲存空間,但相應的增加了查表時的計算量,其原理大致如下:

  建表過程:

  先對原始資料“000000”進行一次HASH運算得到“670B1E”,再對HASH值進行一次R運算,R是一個定製的演算法可以將HASH值對映到明文空間上(這裡我們的明文空間是000000~999999),R運算後得到“283651”,再對“283651”進行hash運算得到“1A99CD”,然後在進行R運算得到“819287”,如此重複多次,得到一條雜湊鏈。然後再選用其它原始資料建立多條雜湊鏈。最終僅將鏈頭和鏈尾儲存下來,中間節點全都去掉。

  查表過程:假設拿到了一條HASH值“670B1E”,首先進行一次R運算,得到了“283651”,查詢所有鏈尾是否有命中,如果沒有,則再進行一次HASH、一次R,得到了“819287”,再次所有鏈尾,可以得到看出已經命中。這樣我們就可以基本確認“670B1E”對應的明文就在這條鏈上,然後我們把這條鏈的生成過程進行重新計算,計算過程中可以發現“000000”的HASH值就是“670B1E”,這樣就完成了整個查表過程。這種表就是“預計算雜湊鏈”。這種方式存在一個問題,多條鏈之間可能存在大量的重複資料,如下圖所示:

  為了解決這個問題,我們將R演算法進行擴充套件,一條鏈上的多次R運算採用不同的演算法,如下圖:

  一條鏈上的每個R演算法都不一樣,就像彩虹的每層顏色一樣,因此取名的為彩虹表。

  當然彩虹表除了可以使用者破解HASH演算法外,理論上還可以用於破解對稱加密演算法,比如DES演算法,由於DES演算法金鑰比較短,建立彩虹表破解是完全可行的;但對於AES演算法,由於金鑰比較長,建表幾乎不可行(需要耗時N億年)。

 三、小結

  採用PBKDF2、bcrypt、scrypt等演算法可以有效抵禦彩虹表攻擊,即使資料洩露,最關鍵的“使用者密碼”仍然可以得到有效的保護,黑客無法大批量破解使用者密碼,從而切斷撞庫掃號的根源。當然,對於已經洩露的密碼,還是需要使用者儘快修改密碼,不要再使用已洩露的密碼。

相關文章