銀行閑談 (183) — 銀行是怎樣儲存大家的密碼的呢?大家有沒有擔心過密碼外洩的問題呢?
不知道大家有沒有想過,會不會有一天有一個監守自盜的銀行職員,或是很厲害的黑客,爬進銀行的資料庫,然後偷取大家所有的賬戶名稱及密碼呢?
大家真的不用擔心,除了因為根本沒那麼容易開啟這個資料庫以外 (會有重重關卡,還會加密的嘛),還因為銀行從來都不會「直接儲存」大家的密碼,所以就算監守自盜也好、專業黑客也好,就算能偷到這個資料庫再解密也是得物無所用的。
其實不單單是銀行喇,有良心的企業都不會「直接儲存」大家的密碼的。不過,既然不會「直接儲存」,那企業又如何核對大家的密碼呢?
今天便和大家科普一下吧。
怎樣儲存密碼,又可以用來驗証,又不怕被偷呢?
假設大家是一場中世紀秘密宴會的主人,宴會只限受邀的賓客進入。各個賓客會一早收到你發給他們的通關密碼,只要他們到達會場,先報上名來 (中世紀沒有身份証、也沒有照片,你說你是華田我便信的喇),再說出正確的通關密碼便可以進入宴會場地了。
有人拿著密碼闖關,也要有忠心的守門人手持密碼表核對身份才行。可是在宴會前,你收到情報有強力部門試圖偷取守門人手上的密碼表,這怎麼辦呢?
這個時候你的謀士就向你提出了一個建議:
「主人,我們大可不必把所有密碼直接寫下,而是把這些密碼先『改頭換面』一下才交給守門人就好喇!」
「那怎麼核對密碼呢?我要預先通知所有賓客這個『改頭換面』後的密碼嗎?」
「主人,絕對不用驚動所有賓客,所有賓客根本不用知道這件事情。我們只要同步把『改頭換面』的步驟也寫下來交給守門人,賓客來到,如常要求他們講出密碼,守門人再按部就班把密碼『改頭換面』一下,才與密碼表核對就好喇!」
「那有什麼分別!?現在有個賓客 A,假設密碼從『OLD』經過『改頭換面』後變了『NEW』,雖然『NEW』不會寫下來,可是因為『改頭換面』的步驟也寫了在紙上,那拿著『NEW』不就是可以『反推』出本來的密碼就是『OLD』了嗎?那有什麼用呢?」
「主人,絕對不用擔心,只要這個『改頭換面』的步驟是『順做容易反做難』就好,就是說從本來的『OLD』變成『NEW』是極容易的,反過來從『NEW』變成『OLD』卻極困難,這就算密碼表被偷,強力部門能偷到的只是一堆『NEW』的密碼。
拿著一堆『NEW』是沒用的,因為我們要的是賓客講出『OLD』,再經過『改頭換面』變成『NEW』才算過關的,如果賓客直接說出『NEW』,經過『改頭換面』後就會變了『STH ELSE』,所以這是騙不了我們的!」
「世上有這麼稀奇的東西?」
「主人,當然有!這東西叫『哈希算法』(又名『散列函數』;英文叫 Hashing) ,很厲害吧!」

什麼是「哈希算法」 (Hashing) 呢?
哈希算法有很多種,不過功能上都是把一堆「OLD」系統性地變成「NEW」,而同步具有幾個重要的特性:
- 高效性:即拿著 OLD哈希成 NEW 是一件程序上簡單低耗量的活動。
- 單向性:即拿著 OLD 哈希成 NEW很直白,反過來拿著 NEW 反哈希 (reverse hash) 成 OLD 卻很困難。在密碼儲存上,這確保就算資料庫整個被偷了,也能防止黑客從 NEW 反哈希成 OLD了。
- 謎題友好性:即拿著 OLD 哈希成 NEW 很簡單很直白,可是要預先判斷出 NEW 或控制 NEW 是極難的,這也意味著只要大家把 OLD 改動一點點,NEW 就會變得完全一樣了。
- 防碰撞特性:即當拿著 OLD-1 哈希成 NEW 後,要多找一個 OLD-2 也能哈希 NEW 是很困難的。在密碼儲存上,這防止了兩個不同的密碼 (OLD-1 和 OLD-2) 因同步哈希成同一個 NEW 後皆能成功驗証的情況。
這樣講好像很複雜,以 SHA-1 算法示範一下就好。
SHA-1 的簡單示範
我利用 Python 以 SHA-1 哈希算法分別對 “Bank of Watin”、 “Bank of Watin!” 和 “Bank of Watin!!” 作了 3 次換算,結果如下:

Sha-1 hash of Bank of Watin is c61450cca32c7cd05190886c27f6cf6ad1a439a7
Sha-1 hash of Bank of Watin! is fd7a5f9f06699e00cc82f7af73d3d78b02f4fdbc
Sha-1 hash of Bank of Watin!! is a2e4ce439268838aa2959150b73127d519c50f60
這裏大家可以大致理解為 sha-1 算法會把 “Bank of Watin” 這串字變成 “c614…39a7”,即是如果大家的密碼為 “Bank of Watin”,數據庫將儲存 “c614…39a7”,而不會直接儲存 “Bank of Watin” 喇。
當資料庫不幸被黑客入侵,黑客也只會得到 “c614…39a7” 這個 40 位字串 (實際是 一個 160 bits 的數值,不過這不重要喇),而基於「單向性」特質,黑客將沒有簡單辦法輕易把 “c614…39a7” 反哈希變回 “Bank of Watin”。
而又基於「謎題友好性」,大家可以看到只要在“Bank of Watin” 作一點小的的變化,例如在最後加一個 “!”,整串 40 位的字串將由 “c614…39a7” 變成 “fd7a…fdbc”,而 2 串 40 位字串是毫無相似性的!即是說黑客將不能夠透過比對或研究頻率等破譯學方法慢慢把“c614…39a7” 破譯為 “Bank of Watin”。
但又基於「有效性」,當用戶輸入 “Bank of Watin” 時,系統又能極速把 “Bank of Watin” 哈希成 “c614…39a7”,這樣系統便能作出驗証了!
以上的幾個特性令哈希算法廣泛被利用在資料庫儲存密碼上,看到這裏不知道大家會不會放心一點喇?
單有哈希算法是不夠的,因為只要有算力、時間和儲存空間,一切都能破解了
其實擁有以上一切都是不夠的,因為只要知道你用的是哈希算法 (你用什麼算法「可能」是一個秘密,不過算法本身絕對不是秘密,大家可以隨便維基的哦!),理論上簡單如透過暴力破解法 (brute-force attack) ,再加上無限多的算力、時間和儲存空間,便一定可以做到反哈希了。
例如如果我知道資料庫用 SHA-1 作哈希算法,而密碼必定是 0 至 999999 這一百萬個數字之一,當我成功偷取密碼表後,我便可以先把這一百萬個數字先哈希一次,再比對密碼表,我便可以得出所有本來的密碼了。
而基於哈希算法的「有效性」,這其實是一件非常快速的事情。我剛剛用 Python 試了一遍,要哈希一百萬次,2 秒已完成足夠了!而當有了這個哈希表,才成功入侵資料庫,我便等同得到了所有本來的密碼了!

當然如果大家的密碼長一點、複雜一點,要用暴力破解便會困難得多。例如一樣是 6 位的密碼,如果容許「數字 + 小寫字母」,所需時間和空間便會提升超過 2,000 倍,如果容許「數字 + 小寫字母 + 大數字母」,所需時間和空間更會幾何地提升至超過 56,800 倍!
不過不過,低階如我手上這台家用電腦,1.82 秒 x 56,800 倍都只是約 1.2 天的時間便能破解整個資料庫,這對專業黑客來說實在太微不足道了吧。
所以說只要有算力、時間和儲存空間,一切都能破解,更不要說其實還有更高階的破解法 — 例如字典攻擊、彩虹表等等,實在用不上這麼長時間喇!
所以在哈希算法上,負擔任的企業 (例如銀行吧) 會在哈希算法上多加一些功夫,來防止一旦 (經哈希後的) 密碼外洩,黑客也不會那麼容易得到原始密碼,下一期會和大家繼續淺談這些方法喇。
銀行是怎樣儲存大家的密碼的呢?大家有沒有擔心過密碼外洩的問題呢?
這一期有一點點技術性,希望我的解釋能達到「專家不會覺得我太錯、一般人也能看懂」的境界吧。
總結來說,負責任的企業在用戶設定密碼後,並不會把這個密碼直接儲存在資料庫,而是會透過哈希算法 (hashing) 來把密碼變成另一串字串 (hashed value) 放在資料庫裏。
就算萬一這個資料庫外洩,黑客得到這些 hashed value 後,理論上將沒有簡單、直觀的方法將其反哈希 (reverse hash) 成本來的模樣,亦不能透過比較或研究頻率能傳統破譯學方法慢慢推敲出本來的模樣。
可是,只要有足夠的算力、時間和儲存空間,黑客理論上是可以透過暴力破解法、字典攻擊、彩虹表等的方法來比對出本來的密碼,証明單有哈希算法是不夠的!
那還有什麼方法來進一步阻止黑客破譯這些資料庫上的 hasded value 呢?這個下一期銀行閑談再和大家討論吧!
關於華田:
兒時夢想做i-banker,結果做了bank worker,還要是retail那種。過去在各大小銀行不同部門流徙,叫人借錢、催人還錢、審批貸款、出股票app、出借錢app、出信用卡、廣告策劃、銷售管理、分行佈點、生物認證、電子排隊、機器學習、敏捷開發,到現在還未安定下來。不懂財經、不懂經濟,只想談一下「銀行」這回事。2021 年開始 Medium 只會發佈部份文章,想知最新銀行 insider insight,就要訂閱我 Patreon(patreon.com/watin) 喇!2021 年 8 月 Medium 再次改制,讀者可以選擇將一半既 Medium 會費撥繳至你喜歡既作者。如果你想喺 Medium 上面支持我,可以去以下呢條 link (watin.medium.com/membership)登記做會員哦!華田銀行 FB: facebook.com/WatinResearch
華田銀行 IG: https://www.instagram.com/bank_of_watin/
華田銀行 HKET 專欄: https://wealth.hket.com/sraw116/華田銀行