雙因素認證與密碼安全最佳實踐
你已經建立了一個網頁應用程式,使用者正在註冊。但他們的帳戶真的安全嗎?弱密碼和缺少雙因素認證(2FA)是攻擊者最容易入侵的途徑之一。在本指南中,我們將介紹一些實用且歷久彌新的密碼安全與 2FA 最佳實踐,你可以立即實施。
為什麼密碼安全仍然重要
儘管多年來不斷警告,密碼仍然是大多數網頁應用程式的主要認證方式。攻擊者深知這一點,並透過網路釣魚、憑證填充和暴力破解來攻擊密碼。一個外洩的密碼就可能導致帳戶被盜用、資料被竊取和聲譽受損。
強密碼政策和 2FA 能顯著提高攻擊者的門檻。讓我們看看如何正確地做到這兩點。
密碼儲存:正確進行雜湊
永遠不要以純文字儲存密碼。始終使用專為密碼設計的強大且緩慢的演算法進行雜湊。像 SHA-256 這樣的快速雜湊不適合,因為它們會助長快速暴力破解攻擊。
推薦的演算法:
- Argon2id – 密碼雜湊競賽的優勝者,能抵抗 GPU 和側通道攻擊。
- bcrypt – 廣泛支援、經過實戰考驗,且設計上就是緩慢的。
- scrypt – 記憶體硬性,適合防止硬體加速攻擊。
在 Node.js 中使用 bcrypt 的範例:
const bcrypt = require('bcrypt');
const saltRounds = 12;
async function hashPassword(password) {
return await bcrypt.hash(password, saltRounds);
}
async function verifyPassword(password, hash) {
return await bcrypt.compare(password, hash);
}
始終為每個密碼使用唯一的鹽(大多數函式庫會自動處理)。調整成本因子,使雜湊在你的伺服器上耗時約 100-500 毫秒。
真正有幫助的密碼政策
忘記「必須包含符號和數字」這類複雜規則。現代指南(NIST SP 800-63B)建議:
- 最小長度為 8 個字元,但鼓勵使用密碼短語(例如 4 個以上隨機單詞)。
- 檢查是否在已洩露密碼清單中(例如 Have I Been Pwned API)。
- 除非懷疑帳戶被入侵,否則不強制定期更換密碼。
- 允許所有可列印的 ASCII 字元和空格。
- 對登入嘗試進行速率限制,以防止暴力破解。
實施一個簡單的強度計,提供回饋但不阻止合法密碼。
雙因素認證(2FA)方法
2FA 增加了第二個因素:你擁有的東西(手機、硬體金鑰)或你本身的特徵(生物識別)。以下是常見方法,按安全性排序:
| 方法 | 安全性 | 可用性 |
|---|---|---|
| 硬體安全金鑰(WebAuthn/FIDO2) | 高 | 中 |
| 驗證器應用程式(TOTP) | 高 | 高 |
| 推播通知 | 中 | 高 |
| 簡訊驗證碼 | 低 | 高 |
簡訊容易受到 SIM 卡交換和攔截攻擊。盡可能優先使用 TOTP 或 WebAuthn。
實施基於 TOTP 的 2FA
TOTP(基於時間的一次性密碼)是安全性和可用性的絕佳平衡。以下是一個高階工作流程:
- 為使用者生成一個密鑰(例如 32 個隨機位元組,base32 編碼)。
- 建立一個 otpauth:// URI 並顯示 QR 碼,讓使用者用驗證器應用程式掃描。
- 在啟用 2FA 之前,驗證使用者能否生成有效的驗證碼。
- 安全地儲存密鑰(靜態加密)。
- 提供備用碼以供帳戶恢復。
登入時,在驗證密碼後,提示輸入 TOTP 驗證碼。使用 otplib 或 speakeasy 等函式庫進行驗證。
const { authenticator } = require('otplib');
// Generate secret
const secret = authenticator.generateSecret();
// Verify token
const isValid = authenticator.verify({ token: userToken, secret });
允許一個小的時間窗口(例如 ±1 個間隔)以應對時鐘偏差。
WebAuthn:認證的未來
WebAuthn(FIDO2 的一部分)使用硬體金鑰或平台驗證器(Touch ID、Windows Hello)實現無密碼和雙因素認證。它具有抗網路釣魚能力,因為憑證綁定到來源。
實施 WebAuthn 需要:
- 伺服器端挑戰生成和驗證。
- 使用 WebAuthn API 的客戶端 JavaScript。
- 為每個使用者儲存公鑰和憑證 ID。
像 SimpleWebAuthn 這樣的函式庫可以讓這變得更容易。雖然比 TOTP 更複雜,但 WebAuthn 提供了最強的保護。
速率限制和帳戶鎖定
即使有 2FA,你也必須防止對密碼的暴力破解攻擊。實施:
- 按 IP 和按帳戶的速率限制(例如每分鐘 5 次嘗試)。
- 失敗嘗試後的指數退避。
- 重複失敗後鎖定帳戶,並提供安全的解鎖流程(例如電子郵件驗證)。
- 幾次失敗後要求 CAPTCHA。
小心不要永久鎖定合法使用者;使用臨時鎖定並通知使用者。
安全的密碼重設
密碼重設流程是常見的攻擊媒介。遵循以下規則:
- 使用透過電子郵件發送的單次、有時間限制的權杖。
- 不要透露電子郵件是否存在於系統中。
- 如果使用者已登入,要求他們重新認證。
- 密碼重設後使所有工作階段失效。
教育使用者而不責備他們
安全是共同的責任。提供明確的指導:
- 使用密碼管理器生成和儲存唯一密碼。
- 盡可能啟用 2FA。
- 警惕網路釣魚企圖。
應用程式內提示和專門的安全頁面可以提供幫助。
常見問題
基於簡訊的 2FA 比沒有 2FA 好嗎?
是的,簡訊 2FA 比沒有好,但它容易受到 SIM 卡交換和攔截攻擊。為了更強的安全性,優先使用 TOTP 或 WebAuthn。
我應該多久更換一次密碼雜湊演算法?
除非發現漏洞,否則不需要更換。但是,當你升級參數時(例如增加 bcrypt 成本),可以在成功登入時重新雜湊密碼。
我可以將 2FA 與 OAuth 或社交登入一起使用嗎?
可以,但 2FA 通常由身份提供者管理。如果你使用社交登入,請確保你自己的帳戶恢復流程是安全的。
準備好增強應用程式的安全性了嗎?從今天開始實施強密碼雜湊和基於 TOTP 的 2FA。如需更多開發者工具,請查看我們的 JSON Formatter 以快速除錯 API 回應。