[小菜一碟] 使用者的密碼應該雜湊(Hash)存起來?還是加密(Encryption)存起來?

雜湊(Hash)跟加密(Encryption)其實很多人會把它們混為一談,常常以為把一串文字變成另一串看起來像亂碼的文字就是「加密」,這兩者還是不太一 樣的,除了名稱跟定義不一樣之外,對於實際應用上來講最大的差異在於「不可逆」。

雜湊?還是加密?

如果我們拿到一個說是可以加密的工具,那它應該對應會有解密的工具,如果沒有,那就有可能它是雜湊的工具被誤說是加密的工具,讓我們回到標題「儲存使用者的密碼應該用雜湊?還是加密?」,其實我們可以兩個都用,如果非要選一個我會選「雜湊」。

第一、因為雜湊出來的結果是不可逆的,不同的內容雜湊出來的結果「幾乎不一樣」,萬一使用者的密碼被偷走的時候,就不容易被逆向破解出原始密碼。

為什麼會說不同內容雜湊出來的結果「幾乎不一樣」? 因為雜湊結果的長度有限,但是原始內容的長度可以是無限,所以有一定的機率兩份不一樣的內容產生出相同的雜湊結果,這個現象叫「碰撞」,因此雜湊有機會透過碰撞被破解,只是它不是逆向破解出原始內容,2017 年的時候有個新聞,古老的 SHA-1 被 Google 給破解了,用的就是碰撞,不過所費不貲,而且 SHA-1 已經是被建議棄用的雜湊演算法,只要我們不要選擇太脆弱的雜湊演算法,要透過碰撞來破解雜湊的難度是相當相當高的。

第二、「」遺失比加密金鑰遺失的風險低,我們可以透過在原始內容的特定位置插入「特定內容」,使得雜湊結果對比原本僅使用原始內容雜湊的結果大相逕庭,這個特定內容就叫「鹽」。

鹽可以是任意的內容,所以我們就可以把密碼跟鹽加在一起,用一組邏輯重新組合排列之後再雜湊,這樣即使被用了像是彩虹表這種破解方式猜出雜湊前的內容,也不是真正要保護的內容,就算有一天鹽遺失了,要破解出原始內容的難度也是很高。

這裡絕對安全?

最後要跟大家說的是「沒有絕對安全的保護方法」,即使我們雜湊再雜湊、加密再加密,甚至混用不同的雜湊及加密的演算法來保護機敏的資料,也都只是提高被破解的難度,以及延長被破解的時間而已,反而我覺得應該要多加強的是「降低資料遺失後的風險」,除了機敏資料不以明碼保存之外,還有近年來很流行的多因素認證,都可以提高資料遺失後被利用的難度,如果資料沒有被利用的價值,就不會有人花錢、花時間來取得它。

參考資料

C# 指南ASP.NET 教學ASP.NET MVC 指引
Azure SQL Database 教學SQL Server 教學Xamarin.Forms 教學