Password Hashing Functions

專為密碼儲存和金鑰衍生設計的密碼雜湊函數(Password Hashing Functions),它們比通用雜湊函數(如 SHA-256)更適合保護密碼,因為它們內建鹽值(Salt)、慢速計算(抗暴力破解)和部分具記憶體密集特性(抗硬體攻擊)。常見的有 Bcrypt、PBKDF2 、Scrypt、Argon2


Bcrypt

介紹

  • 1999 年由 Niels Provos 和 David Mazières 設計,基於 Blowfish 對稱加密演算法。
  • 廣泛應用於 Web 應用(如 PHP、Ruby、Node.js)的密碼儲存。

用途

  • 網站用戶密碼儲存(如資料庫)。
  • 簡單易用的密碼雜湊方案。

格式說明

bcrypt 的哈希輸出遵循模組化密碼格式(Modular Crypt Format)

結構:$2b$<cost>$<salt><hash>

  • $2b:算法標識,表示使用 bcrypt(早期版本可能為 $2a 或 $2y)。
    • $2a$ 是 bcrypt 演算法的早期標識,用於表示使用 Blowfish 加密演算法的密碼雜湊
    • $2y$ 是 PHP 專為修補 $2a$ 的問題而引入的 bcrypt 標識
    • $2b$ 是 bcrypt 的另一個變體,進一步修補了 $2a$ 和 $2y$ 的一些問題
  • <cost>:工作因子的對數(2 進位),以兩位數字表示,例如 12 表示 2^12 次迭代。
  • <salt>:22 字元 Base64 編碼的 16 字節鹽值(使用 ./A-Za-z0-9 字符集)。
  • <hash>:31 字元 Base64 編碼的哈希值,包含密碼與鹽值的計算結果。

範例$2b$12$abcdefghijklmnopqrstuvwxz1234567890abcdefghijk

  • 算法:bcrypt
  • 成本因子:12(2^12 次迭代)
  • 鹽值:abcdefghijklmnopqrstuv(22 字元)
  • 哈希值:wxz1234567890abcdefghijk(31 字元)

優缺點

  • 優點:成熟穩定,實現簡單,普及度高。
  • 缺點:設計較老(1999 年),抗硬體攻擊能力有限。

工具

  • hashcat:有 bcrypt 格式($2$、$2a$、$2b$、$2y$、$2x$)在 hashcat 中均使用 -m 3200


PBKDF2(Password-Based Key Derivation Function 2)

介紹

  • 2000 年由 RSA Laboratories 提出,基於現有雜湊函數(如 SHA-256)設計。
  • 用於密碼儲存和金鑰衍生,廣泛應用於加密標準。

用途

  • 密碼儲存(如資料庫)。
  • 金鑰衍生(如 AES 加密金鑰)。
  • 標準化應用(如 WPA2、TrueCrypt)。

格式說明

PBKDF2 本身不定義標準的字符串格式,輸出通常是原始二進位數據或十六進位編碼。常見應用中,會將鹽值、迭代次數和哈希值一起存儲,格式由實現決定。

結構:<algorithm>$<iterations>$<salt>$<hash>

  • <algorithm>:底層哈希算法,如 pbkdf2-sha256。
  • <iterations>:迭代次數,如 100000。
  • <salt>:Base64 或十六進位編碼的鹽值。
  • <hash>:Base64 或十六進位編碼的哈希值。

範例(自定義格式):

pbkdf2-sha256$100000$4d0c7b9e8f2a3b4c5d6e7f8091a2b3c4$8c7b9e8f2a3b4c5d6e7f8091a2b3c4d5e6f7a8b9

  • 算法:PBKDF2 with SHA-256
  • 迭代次數:100,000
  • 鹽值:4d0c7b9e8f2a3b4c5d6e7f8091a2b3c4(16 字節,十六進位)
  • 哈希值:8c7b9e8f2a3b4c5d6e7f8091a2b3c4d5e6f7a8b9(32 字節,十六進位)

優缺點

  • 優點:標準化(NIST 認可),支援多種雜湊函數,廣泛相容。
  • 缺點:記憶體需求低,抗硬體攻擊弱,逐漸被 Argon2 取代。


Scrypt

介紹

  • 2009 年由 Colin Percival 設計,最初為 Tarsnap 備份系統開發,後用於密碼儲存和金鑰衍生。
  • 以記憶體密集為特色,專為抗硬體攻擊(如 GPU/ASIC)打造。

用途

  • 密碼儲存(如網站資料庫)。
  • 金鑰衍生(如加密硬碟)。
  • 加密貨幣挖礦(如萊特幣)。

格式說明

scrypt 沒有標準化的字符串格式,輸出通常是二進位或十六進位數據。應用中常自定義格式,包含算法、參數、鹽值和哈希值。

結構:scrypt$<N>$<r>$<p>$<salt>$<hash>

  • <N>:CPU/記憶體成本(2 的冪,如 16384)。
  • <r>:記憶體塊大小(如 8)。
  • <p>:並行度(如 1)。
  • <salt>:Base64 或十六進位編碼的鹽值。
  • <hash>:Base64 或十六進位編碼的哈希值。

範例

scrypt$16384$8$1$4d0c7b9e8f2a3b4c5d6e7f8091a2b3c4$8c7b9e8f2a3b4c5d6e7f8091a2b3c4d5

  • 算法:scrypt
  • N:16384(2^14)
  • r:8
  • p:1
  • 鹽值:4d0c7b9e8f2a3b4c5d6e7f8091a2b3c4(十六進位)
  • 哈希值:8c7b9e8f2a3b4c5d6e7f8091a2b3c4d5(十六進位)

優缺點

  • 優點:記憶體密集,抗硬體攻擊強。
  • 缺點:配置複雜,普及度低於 Bcrypt。


Argon2

介紹

  • 2015 年贏得密碼雜湊競賽(Password Hashing Competition),由 Alex Biryukov 等設計。
  • 現代密碼雜湊函數的首選,取代 Bcrypt 和 Scrypt。
  • 有三個變體:Argon2d(抗硬體攻擊)、Argon2i(抗側信道攻擊)、Argon2id(混合,推薦)。

用途

  • 密碼儲存(網站、應用)。
  • 金鑰衍生(加密系統)。

格式說明

Argon2 遵循標準化的模組化密碼格式

結構:$<algorithm>$v=<version>$m=<memory>,t=<iterations>,p=<parallelism>$<salt>$<hash>

  • <algorithm>:argon2i, argon2d 或 argon2id。
  • <version>:算法版本(通常為 19,即 0x13)。
  • <memory>:記憶體使用量(KB)。
  • <iterations>:迭代次數。
  • <parallelism>:並行執行緒數。
  • <salt>:Base64 編碼的鹽值。
  • <hash>:Base64 編碼的哈希值。

範例

$argon2id$v=19$m=65536,t=3,p=4$4d0c7b9e8f2a3b4c5d6e7f80$8c7b9e8f2a3b4c5d6e7f8091a2b3c4d5

  • 算法:Argon2id
  • 版本:19
  • 記憶體:65536 KB(64 MB)
  • 迭代次數:3
  • 並行度:4
  • 鹽值:4d0c7b9e8f2a3b4c5d6e7f80(十六進位,Base64 編碼)
  • 哈希值:8c7b9e8f2a3b4c5d6e7f8091a2b3c4d5(十六進位,Base64 編碼)

優缺點

  • 優點:最現代,安全性最高,靈活配置。
  • 缺點:較新,普及度稍低,配置需專業知識。


比較表格

特性BcryptPBKDF2ScryptArgon2 (Argon2id)
設計年份1999200020092015
基礎演算法Blowfish任意雜湊(如 SHA-256)Salsa20/8Keccak(SHA-3 相關)
記憶體密集否(低記憶體)否(低記憶體)是(可調)是(可調)
鹽值內建隨機鹽值支援隨機鹽值內建隨機鹽值內建隨機鹽值
計算速度慢(可調工作因子)慢(可調迭代次數)慢(可調記憶體/迭代)慢(可調記憶體/迭代)
安全性高(但抗硬體攻擊弱)高(但抗硬體攻擊弱)高(抗硬體攻擊)最高(抗硬體、側信道)
用途密碼儲存密碼儲存、金鑰衍生密碼儲存、金鑰衍生密碼儲存、金鑰衍生
普及度廣泛廣泛(標準化應用)中等(加密貨幣常見)新興,逐漸普及

phpass

介紹
phpass(Portable PHP Password Hashing Framework)是由 Openwall 的 Solar Designer 於 2000 年代初開發的 PHP 密碼雜湊框架,旨在提供安全、便攜的密碼儲存解決方案。基於 MD5bcrypt(視環境而定)進行多輪雜湊,廣泛應用於 WordPressJoomla 等 CMS 系統,用於安全儲存使用者密碼。

用途

  • 網站用戶密碼儲存(如 WordPress 的 wp_users 資料表,或Joomla的jos_users資料表)。
  • 提供簡單易用的密碼雜湊和驗證方案,適用於各種 PHP 應用。

格式說明
phpass 的雜湊輸出遵循其自定義格式,支援多種演算法,常用格式為 $P$(基於 MD5)或 $H$,若環境支援 bcrypt,則使用 bcrypt 的模組化密碼格式(Modular Crypt Format)。

結構(以 WordPress 的 MD5 模式為例):
$P$B<salt><hash>

  • $P$:表示使用 phpass 框架。
  • $B:表示基於 MD5 演算法,預設進行 8192 次迭代。
  • <salt>:8 字元隨機鹽值(Base64 編碼,使用 ./A-Za-z0-9 字符集)。
  • <hash>:22 字元雜湊值,包含密碼與鹽值的計算結果。

範例
$P$Bsalt1234567890abcdef1234567890a

  • 演算法:phpass(基於 MD5)。
  • 迭代次數:8192 次(固定)。
  • 鹽值:salt1234(8 字元)。
  • 雜湊值:567890abcdef1234567890a(22 字元)。

bcrypt 模式(若環境支援)
若伺服器支援 bcrypt,phpass 會生成 bcrypt 格式的雜湊,結構參考上述 bcrypt說明

優缺點
優點

  • 簡單易用,提供直觀的 PHP API,無需額外依賴。
  • 支援多種演算法(MD5 或 bcrypt),具備環境適應性。
  • 高迭代次數(MD5 模式預設 8192 次)和隨機鹽值有效防止彩虹表攻擊。
  • 高度相容,適用於舊版和新版 PHP 環境。

缺點

  • 預設 MD5 演算法較老舊,現代硬體下抗暴力破解能力不如 bcrypt 或 Argon2。
  • 迭代次數固定(8192 次,MD5 模式),無法像 bcrypt 動態調整成本因子。
  • 未內建支援現代演算法(如 Argon2),在高安全性場景下略顯不足。

工具

hashcat:phpass 的 MD5 模式對應 hashcat 的 -m 400,而 bcrypt 模式對應 -m 3200

md5($pass.$salt)

這種格式常見於早期內容管理系統(如 Joomla 1.x)或自定義應用中

結構:MD5(password + salt):salt

範例:23859aaca71e43048d19e39d4cfd91f4:0FVBITlx9gfL7xCs07bKagEaTFnvv3LN

  • 23859aaca71e43048d19e39d4cfd91f4 是 md5($pass.$salt) 的結果
  • 0FVBITlx9gfL7xCs07bKagEaTFnvv3LN 是鹽值。

工具:hashcat -m 10

其他補充:其他salt組合的還有md5($salt.$pass), md5(utf16le($pass).$salt), md5($salt.utf16le($pass)) 等