前兩天貼了編碼、加密、雜湊的文章,今天接著貼它的續集:

聽說不能用明文存密碼,那到底該怎麼存? - Starbugs Weekly 星巴哥技術專欄

這篇列了幾個方案,從編碼到雜湊,搭配圖文解釋,非常適合貼給同事然後叫他們密碼不要亂存。

真的,只要你同事一說「那我們就用 bas…」就直接把這篇甩在他臉上。

備註:剛剛收到另一篇,感覺也可以拿來甩:密碼存明碼,怎麼不直接去裸奔算了?淺談 Hash , 用雜湊保護密碼

此外黑大也有寫過相關的科普,有興趣的朋友可以參考參考:密碼要怎麼儲存才安全?該加多少鹽?-科普角度

按慣例,這邊也迅速節錄一下、收進筆記庫。


方案一:Base64 編碼

Image

先回顧上一篇的這句:

所謂的編碼並不會修改資料、也沒有任何加密的效果,單純就是換個方式來表達資料而已

沒有加密效果!沒有加密效果!沒有加密效果!而且 base64 的 == 真的太好認了= =

經過 Base64 後的結果很常都是 = 或 == 結尾,所以如果有一天資料庫真的洩漏出去了,駭客也會在第一時間就發現可以用 Base64 解開,然後在很短的時間內得到原本的密碼

那如果不要用 base64,用一些比較冷門的編碼呢?

也不行,雖然這些編碼演算法比較少人在用,但頂多騙騙不懂電腦的路人甲乙。真正的駭客很可能會使用各種方法嘗試要 decode 密碼,所以不管用哪一種編碼都是不安全的,結論就是不要使用編碼來儲存密碼!


方案二:AES256 加密

那用加密呢?加密就會牽涉到保管 key 的問題:

因爲使用者要登入時,後端必須確認使用者輸入的密碼加密後跟資料庫內的 password 是否符合,所以還是必須把 key 放在 server 上。既然是放在 server 上,那駭客就還是有機會拿到

因為公司內的員工可能會知道 key,所以就可以從資料庫得到使用者的密碼。如果你知道 Facebook 的工程師只要想要就能得到所有人的密碼,應該也不太放心吧,尤其很多人都在多個網站使用同樣的密碼

結論就是因為無法保證 key 的安全,所以不建議用加密的方式保存密碼


方案三:SHA1 雜湊

雜湊代表是不可逆的,通常是拿到密碼之後再雜湊一次比對結果:

當使用者 Luka 要登入時,就把他輸入的密碼拿去經過 SHA1 雜湊,如果算出來的雜湊值跟資料庫內那一大串一樣,那就代表 Luka 有極高機率輸入了正確的密碼,所以就放行讓他登入

但因為現在的電腦已經很猛了,所以針對一些長度很短的、常出現的密碼,其實就可以直接拿來比對 SAH1,結果就還是會被猜出來

剛剛的 love1234 之所以可以被破解其實是因為他太簡單了,只要把長度為 8 的字串雜湊值都算過一遍就好。而且小寫字母加上數字也才 36 個字元,算一算 36⁸ 大約才 2.8 兆種組合,很快就可以建一個表出來

如果你的密碼又臭又長又亂、包含了大小寫甚至還有一些怪怪的字元,像是 -y]@7k[BSB@3m]r$.>“R,那以現在電腦的計算速度就還無法破解,因為長度 20 以內由數字、大小寫還有特殊字元組成的字串太多了,算到天荒地老都不見得能算出來

(只到這步的話,感覺平常只要密碼夠長就沒啥問題?)

補充:感謝前輩提醒,SHA1 已經在 2017 年被攻破(Announcing the first SHA1 collision - Security Blog),並在 2020 年被公認不再安全(Critical flaw demonstrated in common digital security algorithm

因此建議不要再用 SHA1 了,請改用更舒適安全的雜湊,例如 SHA256 🤔


方案四:加鹽 & SHA256

哦?聽起來只要密碼夠長、夠亂就沒問題了,那我能不能自己產生隨機字串,把使用者的密碼加長呢?

答案是可以,這就是所謂的 加鹽(Salt)。如果今天有一個新的使用者要註冊,這時我們的後端系統就隨機生成一個長度十的字串稱作 Salt,計算 Hash 時就把使用者輸入的密碼跟 Salt 合在一起算

我現在碰到的密碼處理幾乎都是這種,安心實在。

原本攻擊者遇到簡單的雜湊,可能都已經把各個密碼對應的表都算好了(延伸閱讀:彩虹表

但只要加了鹽,這張準備好的小抄就不能用啦~只要多一兩個步驟,就可以讓駭客算到天荒地老,何樂而不為呢?


方案五:Bcrypt

完全沒看過的東西!馬上節錄文章內的介紹:

雖然 Bcrypt 的名字裡面有個 crypt,但他並不是加密法,而是跟 SHA1 一樣是雜湊演算法,唯一的差別是他計算很慢

計算慢有什麼好處呢?前面有提到 SHA1 的雜湊值之所以可以被查表查出來,就是因為現今的電腦計算太快了,就連建個表反查也不需要太多時間

而 Bcrypt 則是可以透過設定疊代次數讓他變慢,以疊代五次的 Bcrypt 來說,他的計算速度大概比 SHA1 慢 1000 倍。也就是說,假如你原本用 SHA1 計算三天就能反查出所有使用者的密碼,現在卻要花大概八年的時間才可以

竟然就只是,算很慢?但想想還是很有道理,畢竟現在的玩法就是炸裂駭客的時間成本讓他去找別人,這樣看起來其實挺有用的?


補充:Argon2

這篇上推之後,發現蠻多朋朋提到 Argon2 這個香東西,第一次認識。怕忘記,先抓兩篇丟上來:

目前看起來最大的特色是可以自訂 Time Cost、Memory Cost 跟 Parallelism Factor,然後因為太吃記憶體(?) 所以打擊用 GPU 的挑戰者特有效?

晚點再研究研究,先補充上來🤔


最後標一下總結的這一小句。我發現有很多朋友曾經跟我有一樣的迷思:
「安全是不是就等於完全無法被攻破?」但其實不是這樣的。

在資安領域沒有所謂絕對的安全,你只能不斷提高攻擊者的成本,當那個成本高到攻擊者無法負荷時(像是破解一個密碼要租超級電腦連續計算十年),那就可以說是足夠安全了XD

那麼,今天的轉貼就到這邊。我們下次(不敢說明天了)見~