前年我留了一台按固定 IP 對外開放的測試伺服器,某天早上收到雲廠商簡訊:帳號異地登入成功。翻認證日誌,前一晚的 Failed password 有 4.7 萬多條,來源 IP 分散在十幾個網段——不是有人試密碼,是腳本在掃。更難看的是那條成功記錄:使用者名稱 root,密碼是三年前給一台臨時機器隨手設的六位數字。那台機器早沒人用了,我連密碼都想不起來,可 22 埠一直開著。
那次之後我把所有帳號的口令重新理了一遍,才明白「密碼強度」不是靠「加個符號」解決的。
一、破解不是猜,是按數量級枚舉
耗時由兩個變數決定:長度和字元集大小。但口徑必須先說清楚。下面那兩檔速率——一般 CPU 約每秒 10 億次、GPU 叢集約每秒 1000 億次——只適用於攻擊方已拿到口令庫、庫裡是未加鹽快速雜湊(MD5、SHA1 一級)的離線撞庫。對方若改用 bcrypt、Scrypt、Argon2 這類慢雜湊,同樣硬體的有效速率要低三到六個數量級,下表每項時長再乘一千到一百萬倍。
代進這個最壞口徑,結果如下。表裡的數你都能自己除:組合數除以 10⁹ 得秒數,再除以一年的秒數約 3.16×10⁷ 得年數。
| 口令構成 | 組合數 | 每秒 10 億次時的耗時 |
|---|---|---|
| 8 位純小寫字母(26 種) | 約 2.09×10¹¹ | 約 3.5 分鐘 |
| 10 位純小寫字母(26 種) | 約 1.41×10¹⁴ | 約 39 小時 |
| 12 位大小寫加數字(62 種) | 約 3.23×10²¹ | 約 10.2 萬年 |
| 16 位大小寫數字加符號(94 種) | 約 3.72×10³¹ | 約 1.18×10¹⁵ 年 |
規律很直白:每多一位,組合數就乘一個字元集大小,26 的四次方是 456976,多一位就是 456976×26。同一件事也可以寫成熵,粗算式是熵約等於長度乘以 log2(字元集):16 位、94 種字元,log2(94) 約 6.55,16×6.55 約 105 bit;8 位純小寫只有 8×4.70 約 38 bit。我說「幾乎無法破解」依據的是那 105 bit,不是我隨手加的符號。所以我給自己定的順序是:先夠長,再談混合。
二、人寫出來的「複雜密碼」為什麼最先被命中
123456、password、qwerty 這幾個字串在洩漏庫裡反覆出現。NordPass 2024 年那份基於公開洩漏資料(含暗網,約 2.5TB 語料)整理的常用口令榜裡,123456 排第一、password 第四、qwerty123 第五;更早被反覆引用的是 SplashData 從 2011 年起按年發布的那份榜單。兩份榜單口徑逐年不同,別併成一句「常年霸榜」;我只取一個結論:這些字串一定在攻擊方的第一批字典裡。拿到庫後第一件事也不是硬算,是跑字典加變形規則:把 a 換成 @、o 換成 0、首字母大寫再拼年份,Abc@2024、qazwsx 這類鍵盤序列是第一批候選,命中比窮舉快好幾個數量級。我那六位數字危險的地方不在六位,在於它是一段日期——生日、工號、手機號尾數、入職年份這類結構,恰好是人腦最愛寫、也最容易被拼出來的。
另一層風險是重複使用。一個中小站點脫庫,帳號和口令成對流出,腳本會拿同一組合去試主流信箱、支付、雲廠商、網盤。真正淪陷的往往不是主帳號,而是那個被人忘記的老帳號——我那次就是這樣丟的口子。
三、我實際重做的步驟
- 先列清單:信箱、雲廠商、支付、社交、內網系統、還有權限的老服務,按「洩漏後的代價」排序,不按使用頻率。順手發現七八個當年只為領一份資料註冊的帳號,直接註銷或停用。
- 逐行換新口令。我是在隨機密碼產生器裡做的,長度統一取 16,大小寫數字符號全開;要在終端手敲的那幾條勾上排除易混淆字元,去掉
0/O、1/l/I(勾選項標的是這五個字元)。這一步我不敢將就的是隨機源:口令必須由密碼學安全隨機數產生,瀏覽器裡對應crypto.getRandomValues;Math.random是偽隨機,種子一旦被還原,前後那串都能同樣算出來,拿它產生口令等於沒隨機。「在本機跑、不發後端」只解決了傳輸環節,隨機源對不對是另一件事,兩者都得成立。 - 產生完當場存進密碼管理器,不貼備忘錄、不發聊天視窗。我只保留一個主口令,同樣產生得更長,寫在紙上放抽屜——前提是它從不出現在登入介面以外的地方。
- 把 22、3389 這類埠從公網收回,改成金鑰或走通道。這一步和密碼強度無關,但它才是真正止血的地方。
四、別把強度評估當成保證
評估類工具看字元組成、熵值和理論窮舉時間,它衡量的是「隨機性」,不知道你這條口令是不是誰的生日,也不知道它是不是已經躺在某個洩漏庫裡。所以我一般兩步走:先用密碼強度評估看評分和熵,確認不是明顯的弱結構;再單獨問自己一遍「這條口令能不能被認識我的人拼出來」。反過來,隨機產生的 16 位口令即使評分是強,只要在同兩個站點重複使用,風險立刻掉到最低檔。
- 真正決定安全邊界的是對方校驗雜湊的快慢,使用者側控制不了,只能靠不重複使用兜底;這也是第一節那些時長必須帶口徑看的原因。
- 沒有配套措施時,定期強改會催生
Abc@2024到Abc@2025這種遞增規律,反而更好猜。不鼓勵週期性強制改不是我個人的偏好,NIST 的 SP 800-63B 就是這個建議:沒有洩漏跡象就不做定期強制更換。我現在的做法是只在有洩漏跡象時換。 - 兩步驗證的優先級高於把口令從 16 位加到 24 位。
- 手機號、工號、信箱前綴這三類「個人資訊式口令」要徹底杜絕,同事反向就猜得出來。
五、常見疑問
Q:密碼是不是越長越好,有必要超過 20 位嗎?
一般帳號 16 位混合隨機已經夠,再加長的收益主要是心理層面。該花力氣的是不重複使用和兩步驗證。
Q:符號必須加嗎?
加符號擴大了字元集,等長下確實更費時間;但如果因此必須靠規律記憶、開始重複使用,就得不償失。長度和隨機性優先。
Q:在網頁上產生的口令會不會被伺服器拿走?
這類工具的機制我確認過:口令在瀏覽器本機產生,不發後端、不寫日誌,不存在產生過程被聽到。更要緊的是隨機源得是密碼學安全隨機數,Math.random 那種可反推的偽隨機不算。真正要防的是產生之後的保管——貼進聊天視窗、郵件或截圖才算洩漏。
Q:十幾個帳號根本記不住怎麼辦?
不要試圖記。密碼管理器負責記每條隨機口令,你只記一個主口令;自動填入涵蓋日常大多數登入,但支付和雲廠商我建議手動輸入,避免被填進錯誤的網域。
Q:怎麼知道自己的口令已經洩漏了?
兩類訊號:信箱裡的異地登入和異常驗證碼請求,以及公開的資料洩漏查詢。收到告警先改信箱口令,它是所有其他帳號的重設入口。
那台被掃的伺服器給我的最大教訓不是「密碼要複雜」,而是:攻擊方永遠挑最弱的入口,而最弱的入口通常是你已經忘記它還存在的那個。列清單、按丟掉後的代價排序、從第一行開始換,比定一個「以後都用 24 位」的口號現實得多。