跳至主要內容
>_ITDITD網站資安平台

資安指南

如何安全儲存密碼 —— 雜湊與加鹽的正確做法

使用者的密碼該如何存進資料庫?明文為什麼危險、為什麼只做雜湊還不夠、為什麼需要為每個使用者加鹽,以及真正的關鍵——慢雜湊(bcrypt/Argon2/scrypt)的選型、設定與既有系統的遷移,統統按順序講給開發者聽,且不涉及攻擊手法。還會點出自行實作的那些坑。

發布於 2026-06-27 更新於 2026-06-27 閱讀時間 2 分鐘

「使用者的密碼,到底該怎麼存進資料庫才對?」——這是每個做服務的人都必然會撞上一次的問題。答案很明確。我們不涉及攻擊手法,只按順序講清楚安全的儲存方法

為什麼明文、加密、裸雜湊都不行

我們按資料庫遲早會外洩這個前提來考慮。一旦外洩,不同的儲存方式造成的損失天差地別。

  • 明文:外洩的瞬間所有密碼一覽無遺。再加上重複使用同一密碼,使用者在其他服務上的帳號也會被連鎖攻陷。最糟。
  • 加密(可逆):有金鑰就能還原=金鑰一起外洩就等同於明文。密碼本就沒有讀回來的必要,因此可逆這件事本身毫無意義。
  • 裸雜湊(MD5/SHA-256):快速雜湊讓攻擊者能高速嘗試海量候選。常見密碼會被彩虹表或暴力破解還原出來。

走到安全為止的「四個階段」

把它理解成給弱方式一步步疊加對策的過程,會很快上手。

① 明文:一外洩就全完
↓ 改為單向
② 裸雜湊:扛不住彩虹表
↓ 為每個使用者加鹽
③ 加鹽雜湊:彩虹表失效,但暴力破解依舊很快
↓ 故意放慢
④ 加鹽+慢雜湊(Argon2id / bcrypt):這才是正解
明文 → 裸雜湊 → 加鹽 → 慢雜湊。只有走到最後一步,才真正算得上『安全的儲存』。

要點在於,鹽和慢雜湊的職責是不同的負責讓「預計算(彩虹表)和批次破解重複密碼」失效。慢雜湊負責把「暴力破解的速度壓到不現實的水準」。兩者齊備,才第一次稱得上安全(→ 什麼是雜湊化)。

實務:現在就該做的事

1

使用 Argon2id(或 bcrypt)

新專案把 Argon2id 作為首選。它還能要求消耗記憶體,因此對 GPU 暴力破解很有抵抗力。如果更看重成熟穩定的實作,bcrypt 在實務中也完全夠用。兩者都直接使用標準函式庫的實作

2

鹽交給「自動」去做

bcrypt/Argon2 會為每個使用者自動產生鹽,並把它一併塞進雜湊字串裡。你不需要自己另存一欄鹽。手動去拼 MD5(salt + password),正是不該犯的典型錯誤。

3

按執行環境設定成本(強度)

把 bcrypt 的成本係數、Argon2 的記憶體・迭代・並行度,設到正常登入在體感上察覺不到延遲的範圍內的最大值。伺服器越快,攻擊者也越快,所以要以年為週期複核並上調

4

驗證用標準的比對函式

登入時,把已存雜湊與輸入用函式庫提供的比對函式進行比對(很多實作已經做成了對時序差有所防範的常數時間比較)。不要自己寫字串相等判斷。

5

弱雜湊用「登入時重新雜湊」來遷移

如果已經用 MD5/SHA-256 存了,就在使用者登入成功的那一刻用新方式重新雜湊並覆寫保存。對於尚未登入的部分,可以用 bcrypt 等把既有雜湊再包一層,用這種雙重雜湊暫時提升整體強度。

常見的錯誤做法 vs 正確的實作

常見錯誤

  • 把密碼加密後儲存(金鑰一外洩就全完)
  • 直接存 MD5(password)SHA-256(password)
  • 所有使用者共用同一個鹽
  • 自己手動拼 hash(salt + password)

正確的實作

  • 用 Argon2id / bcrypt 做單向雜湊
  • 鹽按每個使用者分配(由函式庫自動附加)
  • 成本設在體感可接受範圍內的最大值,並定期上調
  • 直接使用標準的雜湊/比對函式

本站的觀點:密碼儲存是該踩在「成熟正解」上的地方

密碼儲存不是一個可以彰顯獨創性的領域。老老實實踩在經過全球驗證的 Argon2/bcrypt 標準實作上,既最安全,維運也最省心。本站的立場是「在這裡不要搞創意發揮」。真正該投入精力的,是從根本上減少對密碼的依賴——把多因素驗證(MFA)做到位,以及未來向通行密鑰(無密碼)遷移。再強的雜湊,也兜不住弱密碼和重複使用。

延伸閱讀

FAQ

Q密碼加密後再儲存不就行了嗎?
A

不行,加密並不合適。加密只要有金鑰就能還原(解密),金鑰一旦外洩,所有密碼就會被還原成明文。密碼對維運方來說也沒有讀回來的必要,因此無法還原的『雜湊化』才是正解。不過裸雜湊還不夠,需要再配合為每個使用者加鹽以及慢雜湊(bcrypt/Argon2)。

Qbcrypt 和 Argon2,到底該用哪個?
A

如果是新專案,Argon2(尤其是 Argon2id)是首選。因為它的記憶體佔用和計算量都可調,能很好地抵禦 GPU 暴力破解。如果更看重既有資產或成熟穩定的實作,bcrypt 在實務中也完全夠用。關鍵在於:無論選哪個,都要『直接使用標準函式庫的實作,絕不自己拼裝』。

Q我已經用 MD5 或 SHA-256 存了密碼,該怎麼遷移?
A

沒法把它們一次性還原成明文(這恰恰是它的優點),所以要在登入時遷移。當使用者成功登入的那一刻,用新方式(如 Argon2id)對輸入的正確密碼重新雜湊並覆寫保存。對於一直沒登入的使用者,還可以用 bcrypt 等把既有雜湊『再包一層』,用這種雙重雜湊暫時提升一下整體強度。