面試官:為什么在忘記密碼時(shí)只能重置密碼,而不能發(fā)送舊密碼?
有一天,Joe 發(fā)現(xiàn)了一個(gè)他常去的論壇書簽,但已經(jīng)有半年沒訪問了。Joe 想看看這個(gè)論壇現(xiàn)在有什么變化,于是他進(jìn)入論壇,輸入用戶名和密碼,卻收到密碼錯(cuò)誤的提示。
幾次嘗試后,系統(tǒng)提示 Joe 使用“忘記密碼”功能。于是 Joe 填寫了他的郵箱,查收了收件箱中的重置密碼鏈接。盡管 Joe 最終通過重新設(shè)置的密碼成功登錄,但有一個(gè)問題讓他百思不得其解:
奇怪,為什么我必須重置密碼?為什么不直接把舊密碼發(fā)到我的郵箱呢?
很多人可能都有像 Joe 一樣的疑問。發(fā)送舊密碼不是更好嗎?為什么要強(qiáng)迫我更改密碼?
這個(gè)看似簡單的問題實(shí)際上涉及到許多信息安全相關(guān)的概念。讓我們慢慢尋找問題的答案,并順便學(xué)習(xí)一些信息安全的基礎(chǔ)知識!
數(shù)據(jù)庫被盜
我們經(jīng)常會看到新聞報(bào)道某個(gè)網(wǎng)站的數(shù)據(jù)再次被盜,所有客戶的個(gè)人數(shù)據(jù)被泄露,比如知名域名托管網(wǎng)站 GoDaddy 之前泄露了 120 萬用戶記錄。
這里我想和大家討論兩個(gè)問題:
- 數(shù)據(jù)這么容易泄露嗎?
- 數(shù)據(jù)泄露可能會帶來什么后果?
首先來看第一個(gè)問題,很多安全漏洞會導(dǎo)致數(shù)據(jù)泄露,而一些攻擊這些漏洞的方法比你想象的要簡單百倍。
圖片
你想象中的黑客可能像下面這樣,輸入一堆你不知道他們在做什么的命令。屏幕顯示出很多黑底白字或綠字的界面,完全看不懂,但他們一操作,網(wǎng)站就被黑了。
但有些漏洞可能通過在地址欄上改幾個(gè)字就能成功攻擊,即使你不懂任何代碼。
舉個(gè)例子,假設(shè)今天有一個(gè)購物網(wǎng)站。買了東西下單后,訂單確認(rèn)并重定向到訂單頁面,頁面上有很多你的數(shù)據(jù),比如姓名、收貨地址、聯(lián)系電話、郵箱等。
然后你發(fā)現(xiàn)訂單頁面的 URL 是:https://shop.example.com/orders?id=14597。
巧合的是,你的訂單號也是 14597。在好奇心驅(qū)使下,你試著把這個(gè)數(shù)字改成 14596,然后按下回車鍵。
一些攻擊是如此簡單和平凡,只需更改一個(gè)數(shù)字,你就可以看到別人的數(shù)據(jù)。如果你知道如何編寫程序,你可以寫一個(gè)腳本自動(dòng)獲取從 ID 1 到 ID 15000 的數(shù)據(jù)。然后你就擁有了這個(gè)購物網(wǎng)站上所有 15000 個(gè)訂單的信息——上萬客戶的個(gè)人數(shù)據(jù)。
這種漏洞有一個(gè)術(shù)語,叫做 IDOR(Insecure Direct Object References),即不安全的直接對象引用。導(dǎo)致這種漏洞的原因是開發(fā)時(shí)工程師沒有注意權(quán)限控制,允許用戶訪問其他人的數(shù)據(jù)。
有些人可能認(rèn)為我只是為了在本文中說明問題而簡化了事情,但現(xiàn)實(shí)中的攻擊并不像這個(gè)例子這么簡單。
這句話只對了一半。大多數(shù)網(wǎng)站確實(shí)沒有這么明顯的漏洞,攻擊方法也更復(fù)雜。然而,令人恐懼的是,有些網(wǎng)站就是這么簡單——改一個(gè)數(shù)字就能訪問別人的數(shù)據(jù)。
圖片
例如,這兩個(gè)是真實(shí)的 IDOR 漏洞:
- xarefit 有訪問/下載所有會員個(gè)人數(shù)據(jù)的權(quán)限。
- DoorGods 的 IDOR 導(dǎo)致個(gè)人數(shù)據(jù)泄露。
今后,只要你在 URL 欄看到這種數(shù)字,你可以嘗試做一些更改。即使你不會編寫程序,也可能發(fā)現(xiàn) IDOR 漏洞。
個(gè)人數(shù)據(jù)泄露后會怎樣?
我們已經(jīng)看到了從防御不力的網(wǎng)站泄露個(gè)人數(shù)據(jù)是多么容易。
那么,數(shù)據(jù)泄露后會對用戶產(chǎn)生什么影響呢?
最直觀的體驗(yàn)應(yīng)該是詐騙電話,比如某些購書網(wǎng)站或酒店預(yù)訂網(wǎng)站。他們打電話給你,聲稱需要分期退款,并為了獲取你的信任,他們甚至可以告訴你你買了哪本書,預(yù)訂了哪個(gè)房間,甚至你的家庭住址和全名。
詐騙團(tuán)伙能如此清楚地掌握這些信息,都是因?yàn)閿?shù)據(jù)泄露。
但除了這些個(gè)人數(shù)據(jù),還有兩樣?xùn)|西可能會泄露:你的賬號和密碼。
你可能會想:“這只是一個(gè)賬號和密碼,我只要更改該網(wǎng)站的密碼然后再用不就行了嗎!”
事情可能并沒有你想的那么簡單。如果你沒有使用密碼管理軟件,我大膽猜測你所有的密碼可能都是相同的。因?yàn)楹ε掠洸蛔。藗兺鶗λ芯W(wǎng)站使用相同的密碼。
如果此時(shí)你的賬號和密碼被泄露,黑客能否嘗試在其他服務(wù)上使用這些憑證呢?
他們可以使用這些憑證登錄你的 Google 賬戶或 Facebook。使用相同密碼的人就會被黑。所以雖然最初看起來只是一個(gè)購物網(wǎng)站被攻破,但其后果可能導(dǎo)致你的 Google 和 Facebook 賬戶也被黑。
因此,有時(shí)某個(gè)網(wǎng)站的賬戶被黑,可能并不是因?yàn)樵摼W(wǎng)站存在問題,而是黑客在其他地方獲取了你的登錄信息,并嘗試在這里使用這些信息而意外成功。
對于網(wǎng)站開發(fā)者來說,保護(hù)用戶數(shù)據(jù)至關(guān)重要;保護(hù)密碼也很重要。有沒有好的方法可以保護(hù)密碼呢?
加密?
使用某些算法加密密碼意味著將加密結(jié)果存儲在數(shù)據(jù)庫中,因此即使被盜,除非黑客有解密方法,否則他們無法輕易訪問。
這聽起來像是最安全的方法;然而,另一個(gè)問題隨之而來——開發(fā)人員仍然知道如何解密,這可能導(dǎo)致工程師濫用他們的訪問權(quán)限,了解每個(gè)用戶的實(shí)際密碼,出售信息或自己利用這些信息。
嗯……似乎我們陷入了困境,因?yàn)殚_發(fā)人員必須知道數(shù)據(jù)庫中存儲的確切密碼,對嗎?否則,在登錄時(shí)如何確認(rèn)用戶名和密碼組合是否匹配呢?
此外,已經(jīng)聽起來夠安全了,我們?nèi)绾问顾踩??讓網(wǎng)站開發(fā)者無法解密或知道我們的實(shí)際密碼,不是應(yīng)該足夠安全了嗎?
答對了!這正是需要做的!
沒有人知道你的密碼,包括網(wǎng)站本身
事實(shí)上,網(wǎng)站的數(shù)據(jù)庫并不存儲你的密碼。
更準(zhǔn)確地說,它不存儲你的“原始密碼”,而是存儲密碼經(jīng)過某種操作后的結(jié)果。最重要的是,這種操作是不可逆的。
為了給出一個(gè)直接的對比例子,假設(shè)今天有一個(gè)非常簡單的算法可以轉(zhuǎn)換密碼。轉(zhuǎn)換方法是:“數(shù)字保持不變,英文字母替換為數(shù)字(a 變成 1,b 變成 2……z 變成 26)”,以此類推。每個(gè)字母被替換為相應(yīng)的數(shù)字,不區(qū)分大小寫(暫時(shí)假設(shè)沒有符號)。
如果密碼是 abc123,轉(zhuǎn)換后變成 123123。
在用戶注冊期間,網(wǎng)站將用戶輸入的 abc123 轉(zhuǎn)換為 123123,然后將其存儲在數(shù)據(jù)庫中。因此,數(shù)據(jù)庫中存儲的密碼是 123123,而不是 abc123。
當(dāng)用戶登錄時(shí),我們使用相同的邏輯再次轉(zhuǎn)換他們的輸入。如果轉(zhuǎn)換后匹配,那么我們不就知道密碼是正確的嗎?
黑客竊取數(shù)據(jù)庫并獲取這組密碼 123123 后,他們難道不能推斷出它最初是 abc123 嗎?不,不,不——事情沒有這么簡單。
123123,abcabc,12cab3……這些密碼散列后,不還是 123123 嗎?所以,即使你知道轉(zhuǎn)換規(guī)則和結(jié)果,也無法將其恢復(fù)為“唯一的密碼”,這是這種算法的強(qiáng)大之處!
這種轉(zhuǎn)換稱為散列(hash)。每次 abc123 被散列,結(jié)果總是 123123。但是,從 123123 中,你不能確定輸入必須是 abc123,因?yàn)檫€有其他可能性。
這就是散列與加密的最大區(qū)別。
加密和解密是一對;如果某物可以被加密,那么它也可以被解密。因此,如果你知道加密的密文和密鑰,你可以確定明文。但是使用散列,知道散列算法的結(jié)果并不能讓你反向推理出原始輸入是什么。
這種機(jī)制的最常見應(yīng)用之一是安全地存儲密碼。
在注冊期間,存儲散列密碼在數(shù)據(jù)庫中。登錄時(shí),將輸入的密碼散列并與數(shù)據(jù)庫中存儲的散列值進(jìn)行比較,以驗(yàn)證其正確性。即使黑客竊取數(shù)據(jù)庫中的數(shù)據(jù),他們也不知道用戶的密碼,因?yàn)樗麄儫o法反向推理出原始密碼。
這就是為什么當(dāng)你忘記密碼時(shí),網(wǎng)站不會告訴你原始密碼,因?yàn)榫W(wǎng)站本身也不知道!
所以你不能“找回密碼”,只能“重置密碼”,因?yàn)橹刂靡馕吨爿斎胍粋€(gè)新密碼,然后網(wǎng)站將新密碼散列并存儲在數(shù)據(jù)庫中。以后登錄時(shí),它將使用這個(gè)新散列值進(jìn)行比較。
防止預(yù)先計(jì)算攻擊
一些人可能會注意到,這種存儲方法似乎有一個(gè)漏洞。繼續(xù)前面的例子,如果數(shù)據(jù)庫中存儲的是 123123,但我的原始密碼是 abc123,那么如果我使用“abcabc”,散列后也會是 123123。難道我不能這樣登錄嗎?這似乎不對;這不是我的實(shí)際密碼。
當(dāng)兩個(gè)不同的輸入產(chǎn)生相同的輸出時(shí),這種情況稱為碰撞(hash collision)。碰撞是不可避免的,但如果算法設(shè)計(jì)得好,碰撞非常罕見——罕見到幾乎可以忽略不計(jì)。
前面提到的轉(zhuǎn)換規(guī)則只是為了說明問題。實(shí)際使用的算法要復(fù)雜得多;即使只有一個(gè)字母的差異,結(jié)果也會大不相同。以 SHA256 為例:
abc123 => 6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090 abc124 => cd7011e7a6b27d44ce22a71a4cdfc2c47d5c67e335319ed7f6ae72cc03d7d63f
相似的輸入會產(chǎn)生完全不同的輸出。
前面提到的不安全散列算法的例子應(yīng)該避免,或者避免自己設(shè)計(jì)算法。建議使用密碼學(xué)專家設(shè)計(jì)的算法,如上面提到的 SHA256。
使用這些算法時(shí),還應(yīng)特別注意其安全性。某些算法雖然由專家設(shè)計(jì),但已被證明不安全。例如,使用 MD5 存儲散列密碼被認(rèn)為是不安全的。
僅存儲散列值可以嗎?
對不起,僅存儲密碼的散列值是不夠的。
為什么呢?不是說結(jié)果無法逆向推理嗎?為什么這還不夠?
雖然無法逆向推理結(jié)果,但攻擊者可以利用“相同輸入總是產(chǎn)生相同輸出”的特性,預(yù)先構(gòu)建一個(gè)包含人們數(shù)據(jù)的數(shù)據(jù)庫。
例如,假設(shè)有一個(gè)非常常見的密碼“abc123”,其散列值是“6ca13d”。攻擊者可以預(yù)先計(jì)算并將此關(guān)系存儲在他們的數(shù)據(jù)庫中。因此,攻擊者的數(shù)據(jù)庫可能包含一百萬組最常見的密碼,每組都與其對應(yīng)的散列值配對。
然后,他們只需在自己的散列數(shù)據(jù)庫中搜索“6ca13d”。通過查找表,他們可以發(fā)現(xiàn)原始密碼是“abc123”。這種方法不涉及逆向算法;它只是使用現(xiàn)有數(shù)據(jù)進(jìn)行查找。
為了防御這種攻擊,還需要做另一件事,叫做加鹽(salting)。是的,就像實(shí)際的鹽一樣。通常,為每個(gè)用戶生成一個(gè)唯一的鹽——例如 5ab3od(實(shí)際上會更長,可能是16個(gè)或更多字符)。然后我的密碼“abc123”會與我的鹽結(jié)合,變成“abc1235ab3od”,然后將其作為散列的輸入。
為什么要這樣做呢?
因?yàn)橄啾扔趦H使用“abc123”,找到“abc1235ab3od”在攻擊者的預(yù)計(jì)算表中可能性顯著降低。此外,增加長度使暴力破解更加困難。結(jié)果,密碼變得更難破解。
結(jié)語
當(dāng)你忘記密碼時(shí),網(wǎng)站不會將密碼發(fā)送給你,因?yàn)榧词故蔷W(wǎng)站本身也不知道你的密碼。雖然這聽起來不太可能,但事實(shí)確實(shí)如此。出于安全原因,這是一個(gè)必要的措施。
為了實(shí)現(xiàn)這個(gè)目標(biāo),背后最重要的技術(shù)原理是散列?!跋嗤拿艽a將生成相同的散列值,但從散列值無法反向推理出原始密碼”——這就是其中的秘密。
相反,如果你發(fā)現(xiàn)某個(gè)網(wǎng)站可以找回你的密碼,那么你應(yīng)該更加謹(jǐn)慎,因?yàn)樗赡茉谄鋽?shù)據(jù)庫中存儲了實(shí)際的密碼,而不是散列值。在這種情況下,如果有一天數(shù)據(jù)庫被黑,賬號信息包括密碼被黑客竊取,他們可以知道你的實(shí)際密碼并嘗試在其他服務(wù)上使用。
關(guān)于密碼管理,現(xiàn)在瀏覽器也有功能可以自動(dòng)生成并記住密碼,或者你可以使用現(xiàn)成的密碼管理軟件,它可以為不同的網(wǎng)站創(chuàng)建不同的密碼。