繁體中文(台灣)
  • auth
  • password
  • security
  • hashing
  • bcrypt
  • argon2
  • sha1
  • sha2
  • login
  • sign-in

密碼雜湊的演變

你可能聽過選擇密碼雜湊算法的建議,但你有想過為什麼推薦這些算法嗎?在本文中,我們將探討密碼雜湊算法的演變及其背後的原因。

Gao
Gao
Founder

介紹

如其名,密碼雜湊是一個從密碼計算雜湊值的過程。該雜湊值通常儲存在數據庫中,並且在登錄(簽入)過程中,計算用戶輸入密碼的雜湊值,並與儲存在數據庫中的雜湊值進行比較。如果它們匹配,則用戶通過認證。

在我們深入探討密碼雜湊算法的演變之前,了解其必要性是很重要的。

明文密碼:主要的安全風險

想象一下你是一個網站的用戶,已在上面註冊了一個帳戶。有一天,網站被入侵,數據庫被洩漏。如果網站將密碼以明文形式存儲,黑客可以直接訪問你的密碼。由於很多人會在多個網站上重用密碼,黑客可以利用該密碼進行未經授權的訪問到你的其他帳戶。如果你在你的電子郵件帳戶上使用相同或相似的密碼,情況會更糟,因為黑客可以重置你的密碼,接管你所有相關的帳戶。

即便沒有數據洩漏,在大型團隊中,任何有數據庫訪問權限的人都可以看到密碼。與其他信息相比,密碼高度敏感,你絕對不希望任何人能夠訪問它們。

不雜湊地存儲密碼是個業餘錯誤。不幸的是,如果你搜索“密碼洩漏明文”,你會發現像 FacebookDailyQuizGoDaddy 等大型公司都曾經歷過明文密碼洩漏。很可能許多其他公司也犯了同樣的錯誤。

編碼 v.s. 加密 v.s. 雜湊

這三個術語經常被混淆,但它們是不同的概念。

編碼

編碼是密碼儲存首先要排除的。例如,Base64 是一種將二進制數據轉換為字符串的編碼算法:

了解編碼算法允許任何人解碼字符串並檢索原始數據:

對黑客來說,大多數編碼算法相當於明文。

加密

在雜湊流行之前,加密被用來存儲密碼,比如使用 AES。加密涉及使用一個密鑰(或一對密鑰)來加密和解密數據。

加密的問題顯而易見,即“解密”。加密是可逆的,這意味著如果黑客獲取了密鑰,他們可以解密密碼並獲得明文密碼。

雜湊

雜湊與編碼和加密的主要不同在於,雜湊是不可逆轉的。一旦密碼被雜湊,就無法解密回其原始形態。

作為網站擁有者,你實際上不需要知道密碼本身,只要用戶可以用正確的密碼登錄即可。註冊過程可以簡化如下:

  1. 用戶輸入密碼。
  2. 服務使用雜湊算法計算密碼的雜湊值。
  3. 服務將雜湊值儲存在數據庫中。

當用戶登錄時,過程是:

  1. 用戶輸入密碼。
  2. 服務使用相同的雜湊算法計算密碼的雜湊值。
  3. 服務將雜湊值與儲存在數據庫中的雜湊值進行比較。
  4. 如果雜湊值匹配,則用戶通過認證。

上述過程避免了以明文形式存儲密碼,而由於雜湊是不可逆轉的,即便數據庫被入侵,黑客僅能獲得看似隨機字符串的雜湊值。

雜湊算法入門套件

儘管雜湊看似是密碼儲存的完美解決方案,但事情並不這樣簡單。為了理解原因,我們來探索密碼雜湊算法的演變。

MD5

1992 年,Ron Rivest 設計了 MD5 算法,一種可以從任何數據計算 128 位雜湊值的信息摘要算法。MD5 在各個領域被廣泛使用,包括密碼雜湊。例如,“123456”的 MD5 雜湊值是:

如前所述,雜湊值看似隨機字符串且不可逆。此外,MD5 快速且易於實施,使其成為最流行的密碼雜湊算法之一。

然而,MD5 在密碼雜湊中的優勢也是其弱點。它的速度使其易於受到暴力破解攻擊。如果黑客擁有常見密碼及你的個人信息列表,他們可以計算每個組合的 MD5 雜湊值,並與數據庫中的雜湊值進行比較。例如,他們可能會將你的生日與你的名字或你的寵物名字組合。

當今,計算機比以前更強大,使暴力破解 MD5 密碼雜湊變得容易。

SHA 家族

所以,為什麼不使用生成更長雜湊值的算法呢?SHA 家族似乎是一個好選擇。SHA-1 是生成160位雜湊值的雜湊算法,而 SHA-2 是生成224位、256位、384位和512位雜湊值的雜湊算法系列。讓我們看看“123456”的 SHA-256 雜湊值:

SHA-256 雜湊值比 MD5 更長,且同樣不可逆。然而,還有一個問題:如果你已經知道雜湊值,比如上面那個,你在數據庫中看見完全相同的雜湊值,就知道密碼是“123456”。黑客可以創建一個常見密碼及其相應雜湊值的列表,並將其與數據庫中的雜湊值進行比較。這個列表稱為彩虹表。

Salt(鹽)

為了緩解彩虹表攻擊,引入了鹽的概念。鹽是一個隨機字符串,加入到密碼中然後進行雜湊。例如,如果鹽是“salt”,並且你想用 SHA-256 來雜湊密碼“123456”加上鹽,而不是僅僅:

你應該這樣做:

如你所見,結果與未加鹽的雜湊完全不同。通常,每個用戶在註冊時會被分配一個隨機鹽,並與雜湊值一起儲存在數據庫中。在登錄過程中,使用鹽來計算輸入密碼的雜湊值,然後與存儲的雜湊值進行比較。

迭代

儘管增加了鹽,雜湊值仍易受到隨著硬件變得更強大的暴力破解攻擊。為了增加困難,可以引入迭代(即多次運行雜湊算法)。例如,不使用:

你可以使用:

增加迭代次數使暴力破解更困難。然而,這也會影響登錄過程,因為它變得更慢。因此,需要在安全性和性能之間取得平衡。

中場休息

我們來休息一下,總結一下好的密碼雜湊算法的特徵:

  • 不可逆(抵抗逆向圖像)
  • 難以暴力破解
  • 抵抗彩虹表攻擊

如你所見,鹽和迭代是滿足這些要求所必需的。問題在於 MD5 和 SHA 家族本來不是專為密碼雜湊而設計的;它們被廣泛用於完整性檢查(或“信息摘要”)。因此,每個網站可能都有自己對鹽和迭代的實現,這使得標準化和遷移具有挑戰性。

密碼雜湊算法

為了解決這個問題,已經設計了幾種專門用於密碼雜湊的雜湊算法。我們來看看其中一些。

bcrypt

bcrypt 是由 Niels Provos 和 David Mazières 設計的密碼雜湊算法,廣泛用於許多編程語言。以下是一個 bcrypt 雜湊值的例子:

儘管它看起來是另一個隨機字符串,但它包含額外的信息。我們來解析一下:

  • 第一部分 $2y 表示算法,即 2y
  • 第二部分 $12 表示迭代次數,即 12。這意味著雜湊算法將運行 212=4096 次(迭代次數)。
  • 第三部分 wNt7lt/xf8wRJgPU7kK2ju 是鹽。
  • 最後一部分 GrirhHK4gdb0NiCRdsSoAxqQoNbiluu 是雜湊值。

bcrypt 有一些限制:

  • 密碼的最大長度是 72 字節。
  • 鹽的限制是 16 字節。
  • 雜湊值限制是 184 位。

Argon2

考慮到現有密碼雜湊算法的爭論和限制,2015 年舉辦了一次密碼雜湊競賽。跳過細節,讓我們專注於冠軍:Argon2。

Argon2 是由 Alex Biryukov、Daniel Dinu 和 Dmitry Khovratovich 設計的密碼雜湊算法。它引入了一些新概念:

  • 記憶體困難:算法設計使其難以並行化,令使用 GPU 進行暴力破解變得困難。
  • 時間困難:算法設計使其難以優化,使使用 ASIC(專用集成電路)進行暴力破解變得困難。
  • 抗側信道:算法設計使其抵抗側信道攻擊,例如時間攻擊。

Argon2 有兩個主要版本,Argon2i 和 Argon2d。Argon2i 對側信道攻擊最安全,而 Argon2d 提供了最高的 GPU 破解攻擊抵抗力。

-- Argon2

下面是 Argon2 雜湊值的例子:

讓我們解析一下:

  • 第一部分 $argon2i 表示算法,即 argon2i
  • 第二部分 $v=19 表示版本,即 19
  • 第三部分 $m=16,t=2,p=1 表示記憶體成本、時間成本和並行程度,分別是 1621
  • 第四部分 $YTZ5ZnpXRWN5SlpjMHBDRQ 是鹽。
  • 最後一部分 $12oUmJ6xV5bIadzZHkuLTg 是雜湊值。

在 Argon2 中,密碼的最大長度是 232-1 字節,鹽的限制是 232-1 字節,雜湊值限制是 232-1 字節。這應該能滿足大多數場景。

Argon2 現在可以在許多編程語言中使用,例如 Node.js 的 node-argon2 和 Python 的 argon2-cffi

結論

多年來,密碼雜湊算法經歷了顯著的演變。我們要感謝安全界數十年的努力,使互聯網成為一個更安全的地方。由於他們的貢獻,開發者可以更多地關注構建更好的服務,而不必擔心密碼雜湊的安全性。雖然在系統中實現 100% 的安全性可能是遙不可及的,我們可以採取多樣化的策略來最大限度地減少相關風險。

如果你想免去實施身份驗證和授權的麻煩,歡迎免費試用 Logto。我們提供安全(我們使用 Argon2!)、可靠和可擴展的解決方案,使你能專注於構建你的產品。