前言

幾乎每隔一段時(shí)間,就會(huì)聽(tīng)到“XX 網(wǎng)站被拖庫(kù)”的新聞。之后又會(huì)出現(xiàn)一些報(bào)道,分析該網(wǎng)站使用最多的密碼是什么、有多少等等。

眾所周知,密碼在數(shù)據(jù)庫(kù)中通常是以 Hash 值存儲(chǔ)的,并且還加了鹽。攻擊者即使知道具體的 Hash 算法,也只能暴力破解。照理說(shuō)這是極其費(fèi)勁的,然而現(xiàn)實(shí)中卻總有大量密碼被破解,是什么導(dǎo)致安全性如此脆弱?

究其原因,莫過(guò)于這兩點(diǎn):口令密碼、算法成本。

口令密碼

密碼可以記在很多地方。最常見(jiàn)的,就是記在自己腦袋里。當(dāng)然還可以記在屬于你的物品上,例如小本子、卡片等等,反正不用腦子記,不如設(shè)置的很長(zhǎng)很亂,例如:

QQ:     n5Py 2r8W qGyg 4tU6
GMail:  3TkS mVwQ hUrs wtmA
...

這種無(wú)意義的長(zhǎng)串作密碼,是很安全的。即使它們的 Hash 值以及算法泄露,攻擊者想得到明文,只能暴力窮舉所有組合:

泄露的值是 BF656DEC5DD8BA0B,算法是 f(x)。開(kāi)始窮舉...

嘗試組合                f(x)               結(jié)果
aaaa aaaa aaaa aaaa    02F49B3EA5592B14   ×
aaaa aaaa aaaa aaab    BD4E960D990DA3F3   ×
...          
n5Py 2r8W qGyg 4tU5    4CEA28A904326A26   ×
n5Py 2r8W qGyg 4tU6    BF656DEC5DD8BA0B   √

就算只有字母和數(shù)字,也要近 10^28 次才猜到。這是個(gè)天文數(shù)字,幾乎不可行。所以,這種類(lèi)型的密碼還是很安全的。

然而現(xiàn)實(shí)中這么做的并不多。物品需要隨身攜帶,非常不便,要是弄丟或者被偷,就更麻煩了。除非把它們都背下來(lái),但這不又回到“記在腦袋里”這種方式了!

腦袋確實(shí)很安全,但容量也很有限。像上面那種毫無(wú)規(guī)律的字串,背一句都難,更別說(shuō)多個(gè)了。所以,大家多少都會(huì)選些有意義、有規(guī)律的字串作為密碼,例如 iloveyou2016、qwert12345,或是手機(jī)號(hào)、生日等組合。這種不用死記硬背的字串,就是口令(pass word)。

口令雖然方便,但缺陷也很明顯:因?yàn)樗怯幸?guī)律的,所以猜起來(lái)就容易多了。攻擊者只需測(cè)試常用單詞組合,沒(méi)準(zhǔn)就能猜到了:

泄露的值是 2B649D47C4546A3E,算法是 f(x)。開(kāi)始跑字典...

嘗試組合         f(x)               結(jié)果
...
qwert yuiop     52708233CFFD6BFD   ×
qwert asdfg     CD07933880702B97   ×
qwert zxcvb     343F78782D73AB3A   ×
qwert 12345     2B649D47C4546A3E   √

這個(gè)過(guò)程,就是所謂的“跑字典”。一本好的字典,可以極大的提升猜中幾率。

算法成本

在字典相同的情況下,速度就顯得尤為重要了。每秒可以猜多少次?這得看具體的算法。

例如 MD5 函數(shù),每次調(diào)用大約需要 1 微秒,這意味著每秒可以猜 100 萬(wàn)次?。ǘ疫@還只是單線程的速度,用上多并發(fā)更是恐怖)

由此可見(jiàn),算法越快,對(duì)破解者就越有利。假如每次調(diào)用需要 10 毫秒,那么每秒只能猜 100 次,這樣就足足慢了一萬(wàn)倍!

然而不幸的是,常用的 Hash 函數(shù)都是很快的。因?yàn)樗鼈兩鷣?lái)就有多種用途,并非為口令處理而設(shè)計(jì)。例如計(jì)算一個(gè)大文件的校驗(yàn)值,速度顯然很重要。所以,用 MD5、SHA256 之類(lèi)的“快函數(shù)”處理口令,是不合理的。(包括一些簡(jiǎn)單的變種,例如 MD5(SHA256(x)),仍然很快)。一旦 Hash 值和算法泄露,很容易被“跑字典”破解。

現(xiàn)實(shí)中,由于不少網(wǎng)站使用了“快函數(shù)”來(lái)處理口令,因此數(shù)據(jù)庫(kù)泄露后,大量口令被還原也就在所難免了。

增加成本

雖然 Hash 函數(shù)單次執(zhí)行很快,但我們可以反復(fù)執(zhí)行大量次數(shù),這樣總體耗時(shí)就變長(zhǎng)了。例如: