💡 先搞懂問題:密碼從哪兩條路被猜中
登入這件事,本質上是系統問你一個只有你知道的秘密,再拿去和它記下來的東西比對。這個設計有兩個天生的弱點。第一,比對可以一直重來,只要知道帳號,任何人都能在登入頁一次又一次地試。第二,系統總得在某個地方「記住」每個人的密碼,那份紀錄一旦被偷,攻擊者就能把它帶回家慢慢研究。
想像一棟大樓,管理室用「通關密語」確認住戶身分。有人站在櫃台前一句一句亂猜,管理員看得到,也可以請他先離開,這是第一條路。更麻煩的是第二條路:有人把管理室抽屜裡的密語登記簿整本偷走。回到家裡沒有管理員盯著,他想猜多久就猜多久。這時登記簿「怎麼寫」就決定了損失有多大:如果直接抄寫原文,打開就全部看光;如果每條密語都先改寫成只能單向產生的「指紋」,小偷就只能自己一句一句猜、算出指紋、再拿去比對。
圖一:同一個攻擊者有兩條路。左邊每次嘗試都要經過系統,右邊在攻擊者自己的電腦上進行。
同樣是「猜」,猜法有好幾種
走前門的攻擊者也不只一種做法,差別在於「試哪些帳號」和「密碼從哪裡來」。暴力破解(brute force)是盯著一個帳號,把所有字元組合依序試過;字典攻擊(dictionary attack)一樣盯著一個帳號,但只試常見密碼清單,效率高很多;密碼噴灑(password spraying,也有人譯為密碼潑灑)反過來,拿一兩個常見弱密碼去試大量帳號,每個帳號只試一兩次;憑證填充(credential stuffing,俗稱撞庫)則是拿別的網站外洩的「帳號+密碼」配對,原封不動地來這裡試登。下面這張圖把每種猜法在日誌裡留下的形狀畫出來,可以切換看看,再打開帳號鎖定比較差別。
圖二:每一列是一個帳號,每一格是一次登入嘗試,格子裡是示意用的密碼。字典、噴灑用的都是教科書常見的弱密碼範例。
看完會發現一件關鍵的事:帳號鎖定只擋得住「同一個帳號被試很多次」的暴力與字典攻擊,對每個帳號只試一兩次的噴灑和填充幾乎無效,對離線破解更是完全無關。這也是為什麼防禦不能只靠一招,後面的實驗室會一一拆開來看。
🎮 互動實驗室
五個實驗依序回答五個問題:密碼要多長才夠、鹽到底改變了什麼、看日誌怎麼分辨攻擊、鎖定門檻怎麼設,以及哪種存法最安全。所有畫面只在你的瀏覽器裡計算,不會連到任何外部系統。
1猜完要多久:長度、字元種類與存法的拔河
先選一個密碼「規格」,再看四種情境下攻擊者平均要花多久才猜得到。這裡假設密碼是隨機產生的;人自己想的密碼通常有規律,實際會快得多。
圖三:長條長度用對數刻度,每往右一小段就代表時間多了好幾倍。四種速度都是示意的數量級:線上有防護約每天 100 次、線上無防護約每秒 10 次、離線慢速雜湊約每秒 1 萬次、離線快速雜湊約每秒 1,000 億次(相當於一張高階顯示卡算未加鹽的快速雜湊)。
2加鹽實驗:兩個人用了同一個密碼
amy 和 ben 恰好都設了同一個密碼。下面用真正的 SHA-256 在你的瀏覽器裡計算,看看資料庫裡會存什麼,以及攻擊者手上那張「常見密碼的雜湊對照表」能不能查到。請不要輸入你實際在用的密碼。
圖四:鹽是公開存放在雜湊旁邊的隨機值,登入時系統要用同一段鹽重算才能比對。雜湊只顯示前 12 碼。
3日誌判讀:這是哪一種攻擊?
每一題是一段整理過的日誌或事件描述。依「幾個帳號」「每個帳號試幾次」「密碼從哪來」「有沒有登入失敗紀錄」四個線索判斷。
4帳號鎖定門檻:太鬆會被猜,太嚴會被鎖
調整鎖定規則,看同一個帳號在前兩小時被怎麼對待,以及一整天下來攻擊者能試幾次、一般使用者被誤鎖的機會、有心人故意把大家鎖住的風險。
模型假設(示意):攻擊者沒被擋時每秒可送 10 次;失敗計數每 30 分鐘歸零;一般使用者每次輸入約有四分之一機率打錯,打錯就再試。
5排排看:哪種存法最安全
假設資料庫已經整包外洩。請從最危險開始,依序點選五種存法,排到最安全為止。
📘 原理補完:把比喻接回真正的技術
雜湊不是加密
很多人會說「密碼加密存起來」,但正確做法其實是雜湊,兩者差在能不能倒回去。加密(encryption)是可逆的:有金鑰就能把密文解回原文,適合用在之後還需要讀回內容的資料,例如信用卡資料或檔案。雜湊(hash)是單向的:同樣的輸入永遠得到同樣長度固定的輸出,但沒有任何金鑰可以把它「解回來」。
存密碼時,系統其實不需要知道你的密碼是什麼,只需要確認「你這次輸入的,和當初設定的是同一個」。雜湊剛好只提供這個能力。如果改用可逆加密,金鑰通常和資料庫放在同一台伺服器或同一套系統裡,攻擊者入侵時很容易一起拿走,全部密碼就能一次解開,連最長最複雜的那些也不例外。金鑰該怎麼保管,可以參考 加密與金鑰管理 那一頁。
圖五:加密有回頭路,雜湊沒有。所謂「破解雜湊」其實是重新猜一遍再比對。
| 比較 | 加密 | 雜湊 |
|---|---|---|
| 方向 | 可逆,能解回原文 | 單向,無法還原 |
| 要不要金鑰 | 要,金鑰外洩就全部失守 | 不用(胡椒是額外加上的秘密) |
| 輸出長度 | 大致隨原文長度變化 | 固定長度 |
| 典型用途 | 之後還要讀回的資料 | 完整性檢查、密碼驗證 |
| 拿來存密碼 | 不建議 | 要加鹽並用慢速密碼雜湊 |
這也解釋了「破解雜湊」這個說法:攻擊者不是把雜湊值倒推回去,而是自己猜一個密碼、用同樣的演算法算出雜湊,再看跟外洩的值一不一樣。所以題目裡提到 Hashcat 這類工具,指的是拿到雜湊後在自己電腦上離線猜測;它既不是「解密」,也不是對登入頁面試密碼。對線上登入服務逐一嘗試的,則是 Hydra 這類工具,那會在伺服器上留下大量登入失敗紀錄。
系統實際怎麼存、怎麼比對
下面這張圖把註冊與登入兩段流程拆成七步,按「下一步」逐步看資料怎麼流動。
圖六:資料庫從頭到尾只存鹽與雜湊值,胡椒放在資料庫以外的地方。
鹽為什麼能讓彩虹表失效
沒加鹽時,同一個密碼在任何網站、任何帳號算出來的雜湊都一樣。攻擊者因此可以事先把大量常見密碼的雜湊算好存成對照表,拿到外洩資料後直接查表,不用即時計算。彩虹表(rainbow table)就是這種預先計算的進階版,用「雜湊鏈」的技巧壓縮體積,以一部分計算時間換取大量儲存空間,但本質仍是「替某一種不加鹽的雜湊事先算好答案」。
圖七:同樣是 sunshine,加了鹽之後算出的值完全不同(此處為鹽直接接在密碼前再做 SHA-256 的示意),事先算好的表就派不上用場。
加了鹽之後,每個帳號的雜湊都混進一段不同的隨機值。攻擊者要預先計算,就得替每一種鹽各做一張表,這等於對每個帳號從頭猜起,預先計算的優勢消失了,而且兩個人即使用同一個密碼,資料庫裡也看不出來。鹽不需要保密,通常就和雜湊值存在同一欄或同一列;重點是每個帳號都不同、而且用安全的亂數產生,NIST 要求長度至少 32 位元。
胡椒:藏在資料庫以外的秘密
胡椒(pepper)是一把全站共用、只有應用程式知道的秘密值,在雜湊時額外混進去(例如再做一次帶金鑰的雜湊運算),並且不存在資料庫裡,而是放在硬體安全模組(HSM)、金鑰管理服務或獨立的設定中。NIST 把它列為「建議」做法。它的價值在於:如果外洩的只有資料庫,攻擊者手上缺了胡椒,連開始猜都沒辦法。限制是,如果整台應用程式伺服器都被控制,胡椒可能一起外洩;而且一旦要更換胡椒,舊的雜湊無法直接轉換,需要事先規劃。胡椒是加分題,不能取代鹽與慢速雜湊。
為什麼要用「刻意很慢」的雜湊
MD5、SHA-1、SHA-256 這些一般雜湊,原本的設計目標是替大型檔案快速算出摘要,用來檢查完整性或當數位簽章的輸入,越快越好。問題是,同樣的速度也送給了攻擊者:一張顯示卡每秒可以算上百億次這類雜湊,八位數的弱密碼很快就被試完。MD5 和 SHA-1 另外還有碰撞問題,但就存密碼而言,最致命的是「太快」;SHA-256 雖然沒有碰撞問題,只算一次一樣太快。
密碼雜湊函式(password hashing function)反其道而行:它們有可調整的成本參數(work factor),讓每算一次都刻意花時間,例如 bcrypt 的 cost、PBKDF2 的迭代次數。scrypt 與 Argon2 還會要求大量記憶體,讓攻擊者難以用顯示卡或專用晶片同時跑大量猜測。對正常使用者來說,登入時慢個零點幾秒幾乎感覺不到;對要猜幾億次的攻擊者來說,總成本卻被放大了成千上萬倍。
| 演算法 | 原本用途 | 可調成本 | 吃記憶體 | 存密碼 |
|---|---|---|---|---|
| MD5、SHA-1 | 檔案摘要、完整性檢查(已有碰撞問題) | 否 | 否 | 不適合 |
| SHA-256(單次) | 完整性檢查、簽章前的摘要 | 否 | 否 | 不適合,太快 |
| PBKDF2 | 由密碼導出金鑰,靠迭代次數拉長時間 | 是 | 否 | 可以,常見於需符合 FIPS 的環境 |
| bcrypt | 專為密碼設計 | 是 | 少量 | 可以,注意輸入上限 72 位元組 |
| scrypt | 密碼雜湊與金鑰導出 | 是 | 是 | 可以 |
| Argon2id | 2015 年密碼雜湊競賽勝出者的變體 | 是(時間、記憶體、平行度) | 是 | 可以,OWASP 列為首選 |
← 表格可左右滑動 →
成本參數要隨硬體進步定期調高,例如 OWASP 目前建議 PBKDF2-HMAC-SHA256 至少 60 萬次迭代、bcrypt cost 至少 10。實際數值請以當時最新的指引為準。
防禦要分層:每一招各擋什麼
回頭看圖一的兩條路,每一種防禦只對某些攻擊有效。點圖上的任一列,看看它擋得住什麼、擋不住什麼。
圖八:實心圓是主要防線,半圓是有幫助但不完整,空心是幾乎無效。「暴力」一欄也包含字典攻擊。
除了圖上的幾項,還有兩個常考的細節。第一,忘記密碼流程不應該把新密碼直接寄給使用者,而是寄一個有時效、只能用一次的重設連結。第二,設備或系統的廠商預設密碼,上線前一定要更改,因為預設值通常公開在說明書裡,等於字典的第一頁。多因素驗證的類型與抗釣魚能力,可以接著看 MFA 與 FIDO2;帳號權限怎麼切,則在 存取控制 那一頁。
密碼政策:NIST 新版與國內實務並列看
美國國家標準暨技術研究院(NIST)的數位身分指引 SP 800-63B,第四版(Rev.4,文件編號 SP 800-63B-4)已在 2025 年定稿發布,取代 2017 年的前一版。它延續並強化了「長度優先、不強迫複雜度、不定期更換、比對外洩清單」的方向,而且多數條文用的是「不得」(SHALL NOT),不只是建議。
理由不難理解。被規則逼著加大寫、數字、符號的人,多半用同一套可預測的方式應付;被逼著每 90 天換密碼的人,則常常只把尾巴的數字加一。下面這張圖把這兩種行為畫出來。
圖九:看起來四種字元都有,卻是攻擊者變形規則裡最先嘗試的那幾種。這不代表字元種類沒用,數學上字元集越大組合越多;問題在於被強迫時,人會用可預測的方式滿足規則。
| 項目 | NIST SP 800-63B-4(2025 定稿) | 國內考題與實務常見(如 GCB) |
|---|---|---|
| 最小長度 | 只用密碼當唯一因子時至少 15 字元;作為多因素的一部分時至少 8 字元;應允許至少 64 字元 | 常見 8 字元以上,伺服器等較嚴格的環境要求更長;實際數值依各版本基準 |
| 組合規則 | 不得強制要求混合不同字元種類 | 常見「必須符合複雜性需求」,要求大小寫、數字、符號中的數種 |
| 定期更換 | 不得強制定期更換;有外洩跡象時則必須強制更換 | 常見設定密碼最長使用期限(例如 90 天)並記錄歷史密碼不得重複 |
| 外洩比對 | 必須比對常用、可預期或已外洩的密碼清單 | 較少明文列為設定項目 |
| 失敗處理 | 必須限制失敗次數,同一驗證器連續失敗不得超過 100 次;可搭配漸進延遲、機器人偵測與風險評估 | 常見連續失敗數次(例如 5 次)即鎖定一段時間(例如 15 分鐘) |
| 其他 | 應允許貼上與密碼管理器;不得使用密碼提示或「母親姓名」這類知識型問題 | — |
← 表格可左右滑動 →
✅ 自我檢測
六題情境題,點選答案後會立即顯示對錯與解析。
目前得分:0/6
🎯 重點整理
- 線上猜測經過登入系統,可以限速、鎖定、要求 MFA;離線破解發生在資料庫外洩之後,只能靠儲存方式拖慢。
- 一個帳號試很多密碼是暴力破解(全部組合)或字典攻擊(常見清單);一個密碼試很多帳號是密碼噴灑;拿外洩帳密配對試登是憑證填充。
- 帳號鎖定擋不住噴灑與填充;鎖定要逐次拉長但設上限,永久鎖定反而讓攻擊者能故意把人鎖住。
- 存密碼用雜湊不用加密;每個帳號一段不同的鹽讓彩虹表失效、同密碼看不出來,鹽不必保密。
- MD5、SHA-1、單次 SHA-256 都太快;應使用 Argon2id、scrypt、bcrypt、PBKDF2 這類可調成本的慢速密碼雜湊,胡椒另存於資料庫以外。
- MFA 讓密碼被猜中或外洩也不夠登入;外洩密碼黑名單與密碼管理器(每站不同的長密碼)直接瓦解字典與撞庫。
- NIST SP 800-63B-4(2025 定稿):長度優先、不強制組合規則、不定期更換、比對外洩清單;國內 GCB 實務仍常見複雜度、定期更換與失敗鎖定,作答看題目依據。