對密碼進行雜湊實際上能保護你免於什麼
密碼雜湊不是魔法。它是在你的使用者資料表外洩那一天,用來控制損害的機制。
目錄
簡短版
對密碼進行雜湊,能在你的密碼資料庫遭竊時保護使用者。
這是它的主要工作。不是唯一細節,也不是完整的安全模型,但這正是我們對密碼進行雜湊、而不是直接儲存密碼的核心原因。
妥善雜湊過的密碼很難被還原。如果攻擊者取得你的使用者資料表副本,他們不應該立刻得知 Alice 的密碼是 Spring2026!。相反地,他們拿到的是一個儲存的雜湊值,需要花時間、金錢和硬體,才能用猜測來測試它。
這個差別很重要。密碼雜湊本身並不是用來讓登入變安全。它無法阻止網路釣魚。它無法阻止某人拿外洩密碼去嘗試你的登入表單。它也無法在登入後保護工作階段 cookie。它所做的是在一個非常特定的失敗情境發生後爭取時間並降低傷害:你的密碼驗證資料儲存區曝光了。
如果你理解這條邊界,就會在演算法、工作因子、重設、記錄與事件應變上做出更好的決策。
什麼是密碼雜湊
密碼雜湊是將單向函式套用到密碼後得到的輸出,通常會搭配唯一的 salt,以及刻意放慢的密碼雜湊演算法。
當使用者建立帳號時,系統大致應該這樣做:
- 透過 HTTPS 接收密碼。
- 產生隨機且唯一的 salt。
- 將密碼和 salt 交給 Argon2id、bcrypt、scrypt 或 PBKDF2 等密碼雜湊函式處理。
- 儲存演算法名稱、參數、salt,以及產生的雜湊值。
- 丟棄原始密碼。
當使用者稍後登入時,系統會用提交的密碼與已儲存的參數,重複相同的雜湊流程。如果產生的雜湊值與儲存的雜湊值相符,登入就會成功。
重點是:應用程式不需要知道原始密碼。它只需要驗證提交的密碼是否會產生預期結果。
這也是為什麼用可逆加密來儲存密碼通常是錯誤模型。如果你的應用程式可以解密每一個密碼,那麼任何竊取解密金鑰的人也可以做同樣的事。密碼通常應該在反向上不可驗證,而不只是被隱藏起來。
雜湊能保護你免於什麼
1. 資料庫外洩後的即時密碼揭露
如果攻擊者竊取了包含明文密碼的資料庫,損害會立刻發生。每一個密碼都會曝光。使用者不只在你的網站上有風險,在任何他們重複使用該密碼的地方也都有風險。
如果資料庫包含妥善雜湊的密碼,攻擊者就得多做很多工作。他們必須猜測候選密碼,使用正確的 salt 與參數對每個猜測進行雜湊,然後比較結果。
對於弱密碼來說,這可能仍然很快。對於強而唯一的密碼來說,這可能不切實際。
雜湊會把災難性的揭露轉變成一場競賽:使用者是否能重設密碼,而你是否能在攻擊者破解許多密碼之前控制住事件?
這並不完美。它仍然是一次外洩。但它是好得多的失敗模式。
2. 針對整個使用者群的大規模攻擊
Salt 是密碼儲存的關鍵部分,因為它能防止攻擊者利用預先計算好的表格,高效率地同時攻擊大量使用者。
Salt 不是祕密。它會與雜湊值一起儲存。它的任務是確保唯一性。
如果兩個使用者選擇相同密碼,唯一的 salt 會確保他們儲存的雜湊值不同。這能防止攻擊者一眼看出許多使用者共用相同密碼。它也能防止傳統 rainbow table 攻擊,也就是攻擊者使用龐大的預先計算密碼到雜湊對照清單。
沒有 salt 時,一個被破解的雜湊值可能揭露所有使用相同密碼的使用者。有了 salt,每一次密碼猜測都必須針對每個使用者分別測試。
3. 快速離線猜測
一旦攻擊者取得密碼資料庫,他們就可以離線猜測。這表示你的登入速率限制、CAPTCHA、IP 封鎖與監控都不再重要。攻擊者可以在自己的硬體上測試猜測。
這就是演算法選擇之所以重要的地方。
SHA-256 和 SHA-512 這類通用雜湊被設計成很快。這對檔案完整性和數位簽章是好事。對密碼儲存則是壞事。
密碼雜湊演算法被設計成緩慢、可調校,有時還具備記憶體困難性。Argon2id、bcrypt、scrypt 和 PBKDF2 都讓你能調整成本參數,使每一次猜測都需要有意義的時間。
Argon2id 普遍被建議用於新系統,因為它可以設定為同時需要 CPU 時間與記憶體,這會讓大規模 GPU 破解變得更昂貴。bcrypt 仍然常見,而且在設定得當時可以接受,不過它有密碼長度處理等限制。PBKDF2 仍用於某些由合規驅動的環境,尤其是在需要 FIPS 驗證元件的地方。
原則很簡單:讓合法登入保持可接受的速度,同時讓數十億次猜測變得昂貴。
雜湊無法保護你免於什麼
1. 網路釣魚
如果使用者把密碼輸入到假的登入頁面,你伺服器上的雜湊幫不上忙。攻擊者會在你的系統看到密碼之前就收到它。
這裡的防禦方式不同:多因素驗證、passkeys、使用者教育、網域衛生、抗釣魚驗證,以及謹慎的密碼重設流程。
密碼雜湊是儲存祕密的後盾。它不是用來防止使用者被誘騙交出那些祕密的防禦措施。
2. 憑證填充
憑證填充是指攻擊者拿從某個服務外洩的使用者名稱與密碼組合,去另一個服務上嘗試。
你的密碼雜湊可能非常出色,但如果使用者重複使用密碼,憑證填充仍然可能成功。
這是針對你的登入表單的線上攻擊,不是針對資料庫的離線攻擊。你需要速率限制、異常偵測、外洩密碼檢查、MFA,以及不會創造簡單阻斷服務機會的合理鎖定政策。
同樣的實務思考也適用於任何公開表單。如果你正在檢視自己的驗證攻擊面,值得讀一讀為什麼你的聯絡表單是你最大的垃圾訊息責任;機制不同,但教訓相似:公開輸入需要濫用控制,而不只是乾淨的後端程式碼。
3. 被記錄或分析工具捕捉的密碼
只有在明文密碼被快速丟棄,而且從未被複製到其他地方時,雜湊才有幫助。
常見失敗包括:
- 在登入失敗時記錄完整請求本文。
- 將密碼傳送到錯誤監控工具。
- 在工作階段重播產品中捕捉密碼欄位。
- 在設計不良的重設或遷移流程中,將憑證包含在 URL 裡。
- 匯入期間儲存暫時性的明文密碼。
這些錯誤會完全繞過密碼雜湊。如果明文落入記錄、備份、資料倉儲或第三方工具,你的雜湊函式就無關緊要了。
把密碼欄位視為有毒資料。在記錄前遮蔽它們。將它們排除在分析之外。讓它們遠離 URL。限制能存取生產環境追蹤資料的人。
4. 不良的工作階段安全性
登入後,使用者的瀏覽器通常會收到一個工作階段 cookie 或權杖。如果該權杖遭竊,攻擊者可能根本不需要密碼。
密碼雜湊無法防禦跨站指令碼、不安全的 cookie、工作階段固定、弱權杖產生方式,或過長的工作階段生命週期。
工作階段 cookie 值得單獨檢視:HttpOnly、Secure、適當的 SameSite、短生命週期的高風險工作階段,以及密碼變更時的伺服器端失效處理。更廣泛的隱私與瀏覽器環境也持續變動,如2026 年 cookies 發生了什麼變化所述。
5. 薄弱的密碼重設與帳號復原
許多帳號接管不是從密碼開始。它們從重設流程開始。
如果重設權杖可預測、存活時間過長、透過 referrer 標頭外洩,或傳送到已遭入侵的電子郵件帳號,密碼雜湊救不了你。
使用高熵重設權杖、短到期時間、一次性使用,以及清楚的使用者通知。由於電子郵件通常是復原管道,基本的網域驗證也很重要。如果你的團隊把 DNS records 視為神祕儀式,可以從開發者友善的 MX、SPF、DKIM 與 DMARC 導覽開始。
演算法選擇:現在該用什麼
對於新應用程式,如果你的平台有良好支援,請使用 Argon2id。它是 Password Hashing Competition 的優勝者,並且是為密碼儲存而設計,包括抵抗高度依賴 GPU 的破解。
合理的現代優先順序大致如下:
- Argon2id,用於可取得支援的新系統。
- bcrypt,用於 Argon2id 不切實際且 bcrypt 支援成熟的情況。
- scrypt,用於記憶體困難設定受到良好支援的情況。
- PBKDF2,用於平台或合規限制要求的情況。
避免使用純 SHA-256、SHA-512、MD5,或像 sha256(password + salt) 這樣的自製組合。快速雜湊不是密碼儲存函式。聰明的自訂構造往往比無聊的標準方案更糟。
也要避免圍繞演算法瑣事發明自己的密碼政策。如果 12 條密碼組成規則清單會把使用者推向可預測模式,使用者並不會因此受益。較長且唯一的密碼、密碼管理器、外洩密碼篩查與 MFA 通常更重要。
成本因子不是設定後就不用管
密碼雜湊有參數。Argon2id 有記憶體、迭代次數和平行度。bcrypt 有成本因子。PBKDF2 有迭代次數。
這些值應該根據你的生產環境來選擇。太低,攻擊者就能便宜地猜測。太高,你的登入系統就會變慢,或容易受到阻斷服務攻擊。
實務上的目標通常是在你的實際伺服器上,每次密碼驗證耗時數十到數百毫秒之間,具體取決於流量與風險。高安全性系統可能會選擇更高。消費者規模的系統可能需要謹慎的容量規劃。
不要從五年前的部落格文章複製成本因子。硬體會變。函式庫會變。你的流量也會變。
定期檢視參數,並規劃重新雜湊。常見模式是將演算法與參數和每個雜湊值一起儲存。成功登入時,如果儲存的參數已過時,就用較新的設定對提交的密碼重新雜湊,並更新記錄。
Peppers:有用,但不是替代品
Pepper 是加入密碼雜湊流程的祕密值,並且與資料庫分開儲存,通常放在 secrets manager 或硬體安全模組中。
不同於 salt,pepper 必須保持祕密。
如果資料庫外洩但應用程式祕密沒有外洩,pepper 可以降低損害。它們在具備良好金鑰管理的成熟環境中最有用。如果同一個攻擊者能同時竊取資料庫與應用程式設定,pepper 的用處就比較有限。
如果你使用 pepper,請謹慎規劃輪替。視設計而定,輪替可能需要使用者再次登入或重設密碼。Pepper 是額外的一層,不是削弱底層雜湊設定的理由。
營運檢查清單
如果你負責一個真實系統,實務檢查清單很短:
- 只使用標準密碼雜湊演算法儲存密碼。
- 每個密碼使用唯一的隨機 salt。
- 新建系統優先使用 Argon2id。
- 在類似生產環境的硬體上調校成本參數。
- 將演算法與參數和每個雜湊值一起儲存。
- 當參數過時時,在登入時重新雜湊。
- 絕不記錄密碼,或將密碼傳送到分析工具。
- 在提交憑證的所有地方使用 TLS。
- 在風險足以支持時加入 MFA 或 passkeys。
- 像保護登入流程一樣認真保護重設流程。
- 準備好強制重設與使用者通知的事件應變計畫。
密碼雜湊並不華麗。它是管線工程。但這正是那種會決定一次外洩究竟是痛苦事件,還是波及所有使用者災難的管線工程。
<!-- tool-cta:start -->
💡 試試看: 使用 Hash Generator 查看相同輸入如何對應到不同演算法,從而具體呈現快速雜湊與密碼級雜湊之間的差異。
<!-- tool-cta:end -->
誠實的心智模型
思考密碼雜湊的最佳方式是:
雜湊無法在使用者輸入密碼時保護密碼。它無法在使用者登入後保護帳號。它無法保護在整個網路上重複使用密碼的使用者。
它保護的是儲存的驗證資料。
這聽起來範圍很窄,但極其重要。資料庫會外洩。備份會外洩。預備環境系統會被複製。供應商會取得他們不該有的存取權。舊匯出檔會在物件儲存中放得比任何人記得的都久。
當這些事發生時,你的密碼儲存設計會決定攻擊者拿到的是密碼,還是一個昂貴的猜測問題。
這就是對密碼進行雜湊實際上能保護你免於什麼。