你的密碼是否在資料外洩中?
資料外洩是指某個服務的密碼資料庫流落到公開場合——而外洩語料就是從數百起這樣的外洩中收集的密碼集合,經過索引,任何人都可以查詢某個密碼是否在其中。如果你的密碼在裡面,攻擊者已經擁有它:它躺在字典裡,被自動拿到每一個能登入的頁面去試。本文解釋這項檢查如何在不透露密碼的情況下工作、“出現過 5200 萬次”到底意味著什麼、為什麼“未找到”不等於健康證明,以及為什麼絕不能把密碼貼進聊天機器人去問它是否安全。要執行檢查,請使用密碼外洩檢查。
什麼是外洩語料
每一起重大外洩都會留下同樣的殘留物:一個使用者名稱和密碼的資料庫——通常以雜湊形式儲存——從一家公司的系統中被複製出來,流轉、出售或公開。單獨看,這些資料庫只是一家公司失守的證據;收集到一起、去重並編入索引之後,它們就變成了別的東西——人們實際使用的密碼的人口普查。Have I Been Pwned 的 Pwned Passwords 語料——本站檢查器查詢的那個——包含來自數百起外洩的十多億個密碼,並且每出現一起新外洩就會增長。它不是理論家編出來的弱密碼清單,而是真實的人選擇、輸入並遺失的密碼的紀錄。
這就是為什麼語料是一面毫不留情的鏡子。你花五秒鐘想出來的密碼——名字加出生年份、球隊加驚嘆號、鍵盤上的連續按鍵加末尾一個數字——很可能已有成千上萬的人以完全相同的形式想出來過,而如果其中任何人在某個被攻破的服務上用過它,它就在語料裡。攻擊者不會像人那樣一次猜一個密碼,他們玩的是撞庫:拿一份外洩的使用者名稱密碼對清單,或一份外洩密碼的字典,每小時自動嘗試數百萬次,對象是各處的登入頁面。語料裡的密碼,就是已經在清單上的密碼。
五字元檢查如何運作
對照一個十億條目的資料庫檢查密碼,聽起來似乎必須把密碼傳送給某個人——多年來,這一直是對每一項外洩檢查服務誠實的質疑。解決辦法是一種叫 k-匿名的技巧,一句話就能說清:服務永遠不知道你問的是哪個密碼,因為它看到的資訊不足以分辨。密碼在瀏覽器中用 SHA-1 做雜湊,得到一個 40 個字元的指紋,只有該指紋的前 5 個字元會被傳送給 Have I Been Pwned。服務傳回所有共享這 5 個字元的指紋後綴——通常大約八百個——瀏覽器再在本地、在你的裝置上尋找自己的後綴。
5 個字元就是關鍵數字。5 個十六進位字元大約有一百萬種可能,因此在十億條目的語料裡,每個前綴大約由一千個密碼共享——相似者足夠多,服務無法識別你的密碼;又足夠少,答案可以裝進一次小小的回應裡。密碼本身沒有任何資訊經過網路:不是密碼,不是它的完整雜湊,甚至不是它長度的一點暗示。同樣的設計也是這項檢查不需要帳號、不需要 API 金鑰、不需要值得注意的速率限制的原因,也是回應可以快取數週的原因:同一個前綴的答案,對每一個詢問者都一樣。本站的密碼外洩檢查正是在瀏覽器中實現這一模型,雜湊在傳送之前先在本地算好。
“出現 N 次”是什麼意思——以及該做什麼
次數大於零,意味著密碼在外洩中出現過那麼多次,而這個數字直接衡量了它會被多早嘗試。數以百萬計的次數——“password”本身出現過五千多萬次——意味著這個密碼是每一次撞庫中最先嘗試的猜測之一,應該在所有使用它的地方都換掉,先從那些保護著其他帳戶的帳戶開始:首先是電子郵件,然後是銀行,再然後是密碼找回路徑。次數很小也不算過關,即使只出現過一次,也說明這個密碼已經在攻擊者的字典裡,而且通常還說明它遵循某種可猜的模式——正是這種模式讓成千上萬個相似密碼也進了語料。
任何次數下的解決辦法都是一樣的:換成一個你在任何地方都沒用過的唯一密碼,保存在密碼管理器裡,而不是記在腦子裡。人類記憶正是重複使用密碼的原因——沒有人能記住一百個互不相同的隨機字串——而管理器是讓唯一性變得負擔得起的工具。用密碼產生器產生替代密碼,保存進管理器,然後在所有用過舊密碼的服務上逐一更換,先換那些能讓攻擊者重設其他帳戶的服務。如果同一個密碼保護著好幾個帳戶,就把它們全部當作已經暴露:攻擊者會把外洩的密碼拿到每一個能登入的服務去試,而不只是它外洩出來的那一個。
“未找到”不意味著什麼
次數為零是個好消息,但有嚴格的限度。它只說明這個密碼沒有出現在該語料所知道的外洩中——僅此而已。它不說明密碼強壯:一個由字典單詞加數字組成的短密碼可能不在語料中,卻仍能在幾分鐘內被猜測攻破,因為猜測不需要密碼先外洩。它不說明密碼安全:外洩浮出水面需要數月甚至數年,一個躺在尚未上報的外洩裡的密碼,在曝光的那一天到來之前,對每一個語料都是不可見的。它也不說明重複使用的密碼沒問題:一個在十個網站使用的密碼,只需一起外洩就會丟掉全部十個,無論今天的次數是多少。
誠實地理解零的方法,是把它看作幾項檢查中通過的一項。這個密碼已知沒有外洩——這一點值得知道,也是這項檢查唯一能告訴你的事。它是否同時足夠長、足夠隨機、只用在一個地方,是另一個問題,檢查回答不了。值得堅持的標準是下面列出的 NIST 記憶祕密指南中的那條:重長度而非複雜性規則,絕不為定期而定期要求更換,並在密碼被選定的那一刻對照外洩語料檢查新密碼——這正是本文描述的檢查。一個長、隨機、唯一、未找到的密碼,就是一個好密碼。去掉這四個屬性中的任何一個,零的意義就不大了。
永遠不要把密碼貼進聊天機器人
問“我的密碼安全嗎?”最危險的方式,是把密碼貼進聊天機器人或 AI 助手直接問它。聊天會保留對話紀錄:你的密碼會被存到別人的伺服器上,按對方的保留政策保存,被用來訓練或調校模型,甚至可能在以後的回答中被原樣引用——引給完全不同的另一個人。同樣的道理適用於任何要求你在表單裡輸入密碼並承諾幫你評判的網站:除非像本站檢查器這樣在本地做雜湊並把機制展示給你,否則就預設密碼正在被傳送、儲存和記錄。外洩檢查之所以值得做,正是因為它可以在不把祕密交給任何人的情況下完成——而當你把祕密貼進聊天去問它時,你已經製造了這項檢查本要發現的那種暴露。
這條規則可以推廣。密碼、API 金鑰、權杖和私鑰,都是絕不能以原始形式輸入聊天、工單、論壇貼文或共享文件的東西——這也是本站設有祕密遮罩工具、用於在分享之前把它們從文字中清除的原因,還有一篇配套文章在貼上之前先遮罩你的祕密。當祕密確實必須交到他人手中時,透過祕密管理器或過期的單次檢視分享連結傳送,並且與討論走不同的管道。而當你需要知道某個密碼是否外洩時,就用為這個問題而建的機制:本地做雜湊,傳送五個字元,剩下的在自己的裝置上匹配。這就是全部的檢查,也是唯一一種不會透過製造新的外洩來回答自己的提問方式。