沒知識真可怕——應用密碼學的笑話之MD5+Salt不安全
阿新 • • 發佈:2019-01-26
這段時間諸多爆庫的新聞,裡面有許多饒有趣味的事情。那些用簡單密碼,或者一個密碼走天下的笑話就不說了,咱說點有內涵的。(這篇文章是給IT界的人看的,如果你看不懂,我會準備一個簡單的“如何辨別密碼安全糟糕的網站”的方法給你,另文描述。)
爆庫之後哀鴻遍野,一大堆人都在裡面嗷嗷亂叫,當然也包括我在內。但是當我嗷了一陣子之後,發現我的G點和大家的居然不一樣,就靜下心來觀察。結果發現就連大多數IT界的人對密碼學這個玩意兒居然都是一無所知的狀態,各種人雲亦云的笑話此起彼伏。當然了,能看懂的也沒幾個。
就比如說MD5不安全這個笑話。
其實也不知道這怎麼就跟爆庫的事情扯到一塊去了,但總歸那幾天就有一堆人上來恨恨地說:MD5不安全,現在還有人用來做密碼的雜湊……好吧,大概對於有些人來說有點深了,這個知識以後我補。咱接著說,“簡直是遜爆了”。當然,原文不是如此,但也差不多了。
言下之意,就是他的知識告訴他MD5是不安全的,而用這些的人大概是沒知識的。而事實上是,這麼說的人同樣沒有知識。為什麼?首先要搞清楚所謂的“不安全”是指哪些問題?
笑點一:MD5被破解啦!
2004年的國際密碼學會議(Crypto’2004)王小云證明了MD5可以被碰撞,至此,MD5不再安全。沒錯,確實不安全了,但是具體是什麼意思呢?大概多數人根本搞不清楚,也就不知道這個不安全是在哪一個場景底下的了。
要說明這個問題,首先要搞懂MD5是一個什麼概念。所謂的MD5實際上是一個雜湊函式,具體說特點如下:
另一個拿來說事的,就是MD5密碼庫如何如何大,比如包含了7.8萬億個密碼。可是……你曉得英文大小寫+數字+2標點共計64種字元,長度是10個字元,總共會有多少個不同的密碼嗎?答案是1,152,921,504,606,846,976個,也就是1,152,921.5萬億個。那個7.8萬億個密碼的密碼庫,只佔有這裡面的百萬分之6.7。
可為什麼大家的密碼還老是洩露呢?那是因為:
- 無論多長多隨意的資訊,最後都轉換成一個固定長度的雜湊值;
- 對於大量不同的資訊,最後出來的雜湊值呈平均分佈;
- 對於特定的一個資訊,最後出來的雜湊值都是相同的。
- 不可逆(用一個固定長度的數值,怎麼可能表示任意長度的資訊呢);
- 難碰撞(假如雜湊值有效範圍是從0到9,那麼對於已知的一個明文平均需要嘗試
115次才能找到一個相同的資訊,對於任意兩個隨機明文的碰撞概率大概是1/N,即1/10。但是,一般來說雜湊值有效範圍都在2的64次方以上,即0到18,446,744,073,709,551,616之間,甚至更多,你可以說是一個天文數字); - 可代表(既然不可逆,難碰撞,你用雜湊值是猜不出原來的資訊,更不太可能偽造一個資訊,其雜湊值完全相同。於是你出示一個雜湊值,就可以證明你持有某個有效資訊,比如密碼)。
- 簽名認證,證明某段資訊沒有被修改;
- 密碼驗證,證明你確實知道某個密碼;
- 其他,比如用在雜湊表的雜湊過程等(這一個場景在某一類稱之為(D)DOS攻擊的場景下有關,但跟密碼安全這種隱私/劫持相關的安全問題沒關係,咱就不討論了)。
- 人的記性很差,所以總會選用比較好記的密碼,也就是弱密碼;
- 人的記性很差,所以總會選擇極有限的幾個密碼用在無窮多的網站上;
- 沒讀過書的人總是那麼多,於是總用很差勁的方式來對待系統的安全部分,尤其是密碼部分。
- 4位純數字,總計1萬個不同的密碼;
- 6位純數字,總計100萬個不同的密碼;
- 8位以內的小寫字母,而且還是某種拼音或者單詞,總計估計不超過1000萬個不同的密碼;
- 即便是8位小寫字母加數字,也就是時2.8萬億個不同組合。
- 暴力窮舉:最笨最慢的方法,讓P'=0...X,找到E(P', k)=C;
- 演算法分析:研究E(),找到其中的弱點,然後P'=0...Y,找到E(P', k)=C,Y
- 密文分析:根據C1,C2,...Cn,找到裡面的蛛絲馬跡,直接找到能解密的 替代函式D'(),或者直接解出C的部分明文P';
- 已知明文攻擊:有選擇的給出明文P1,P2,...Pn,讓對方用E(p, k)計算出C1, C2, ...Cn,通過分析找到k',使得D(C, k')=P;
- 生日攻擊:有選擇的給出明文P1,P2,...Pn,然後直接用這些明文嘗試使用者U1, U2, ...Un,恰巧某些使用者Ux就是用的其中一個明文。這是後面要講的其中一個重點,所謂加鹽就是要解決類似的問題;
- 偷聽:監聽鏈路,等使用者U給出P時即可直接獲得,或者使用者給出的是E(P,k)=C,則下次也可以用同樣的協議給出C,偽裝使用者U。什麼QQ盜號木馬,就屬於這種形式;
- 整鍋端:通過後門漏洞等,直接拿到所有資料和程式,然後進行上面的各種分析和攻擊。本次CSDN為開端的,多數是這種;
- 間諜(找到人,用各種賄賂,直接拿到E()、D()和k,甚至所有移植的C和P,或者自己拿著這些東西出去賣錢)。
- 該站點密碼儲存的方式不好,很可能是計算C=E(P),儲存C;
- 這些使用者的密碼很可能是相同的。
- 該站點不是使用明文儲存密碼;
- 該站點使用的是MD5;
- 該使用者的密碼就是123456。
- 密碼學的理論安全,是建立在就算你知道了所有其他的資訊包括E()、D()的具體演算法,整個加解密的協議,以及儲存密文的方法,乃至所有程式原始碼、資料庫,你只要不知道金鑰k是什麼,對於待破解的密文C是不能得到明文P的,甚至用任意其它明文P'計算出相應的密文C',你也得不到待破解密文C所對應的明文P是什麼;
- 密碼學的應用安全,是建立在破解所要付出的成本遠超出能得到的利益上的。
- 增加演算法所需要的時間(比如那個宣稱雜湊一次至少0.3秒的bcrypt);
- 增加破解所有人的總體時間,等。
- 黑客拿到的只是:使用者A的鹽是aaaa,雜湊值是X8jv8o。使用者B的鹽是bbbb,雜湊值是8go489;
- 首先,標準的密碼庫失效了;
- 其次,每個使用者的雜湊值都不一樣,你無法根據相同雜湊值數量的多少得出哪些是弱密碼;
- 再次,鹽是aaaa,雜湊值是X8jv8o,是無法推匯出密碼是123456,還是abcdef,還是別的什麼東西,不像在簡單MD5的情況下,看到qwerty就知道那是123456;
- 針對每個使用者進行暴力破解;或者
- 針對每一個使用者的鹽,比如aaaa,分別根據弱密碼明文庫,計算MD5(弱密碼明文+aaaa)=鹽aaaa對應的雜湊值,然後再用這個密碼庫去對使用者A進行生日攻擊。對使用者B還得重新根據新的鹽bbbb生成密碼庫……
- 我已經有你的程式了;
- 找到生成密碼雜湊值的入口函式Fuck();
- 拿一個明文密碼庫,在一個使用者賬號上面不停地改密碼,也就是用每一個P不斷地Fuck(P);
- 好了,密碼碰撞庫就出來了。
- 什麼是MD5;
- 加鹽是幹什麼的;
- 密碼學的準則之一是不能依賴於你的演算法不被公開;
- 什麼樣的演算法是安全的,怎麼樣算是安全。
- 單純的使用這種演算法不加鹽,只不過增加了沉沒成本,邊際成本是不會變的,生日攻擊還是存在的;
- 1秒鐘算3個密碼,雖然破解時的成本大大增加了,但是你自己的系統的執行成本也會大大的增加。比如說:原來用MD5時一臺伺服器解決使用者登入問題負載剛好100%,你用這個該死的bcrypt演算法就需要該死的上萬臺伺服器才能解決問題。
- 如果你沒讀過某個領域的至少一本書,最好別隨便發言,否則別人一眼就能看出你是個什麼青年;
- MD5+salt對於大部分中小網站來說已經足夠安全了;
- 你實在信不過MD5,那就用點SHA1之流,在密碼驗證這種場景裡面,已經足夠了,除非你是開銀行或者開淘寶的;
- 身份驗證只是安全的其中一個環節,想想這些庫都是怎麼被偷出來的,想想各種QQ木馬……
- 你在網路上看到的大部分言論基本上屬於在此領域完全無知的人所想象出來的錯誤言論,比如說搜尋“MD5不安全”,除了極少數個別的抄正規網站的報道外,以及個別真正的安全網站裡面的資訊外,幾乎都是各種笑話;
- 在安全這方面,只要你不是專家,你還是當他不存在比較好。和食品安全一樣,在網路安全方面,其實大部分網站這方面做得都很糟糕,你要知道了真實的情況,恐怕沒法用網路上的東西了。