
工程思考 · 教學
密碼管理器推薦
從重複密碼的風險開始,圖解 Vault 加密、TOTP、FIDO2、Passkey、自動填入與備份,並附可展開的算法說明。
本文目錄
現在各個網站都需要帳號密碼,但我想大多數的人都使用著同一套密碼。
這其實很危險,真正的危險點在於,當一個網站出現了洩漏之後,就能拿著洩漏的帳密去每個網站測試。
因此,為了防止這種問題,除了 OTP(但很多人覺得麻煩又不喜歡開),就是密碼管理器了。
很多人的密碼管理器就是 Chrome 內建的,但 Chrome 的問題是,如果其他 app ,或是非網頁的時候怎麼辦?
因此我想介紹一下『密碼管理器』。
補充一下:Chrome/Google Password Manager 在部分手機系統其實也能替其他 App 填密碼,不是完全只能用於網頁。我比較在意的是跨裝置、跨瀏覽器時,能不能維持同一套管理方式。[14]
01 /先說為什麼不能一直用同一組密碼
這種攻擊叫 Credential Stuffing(憑證填充攻擊):攻擊者不用破解每一個網站,只要拿 A 網站外洩的帳密清單,寫程式去 B、C、D 網站批量嘗試。只要其中一個網站也用了相同密碼,就可能登入成功。
密碼管理器解決的是這個問題:每個網站產生不同的隨機密碼,例如 20 字元的隨機字串。人只需要記住管理器的主密碼,不用背每一個網站的密碼。即使網站 A 出事,這組密碼也不能直接拿來登入網站 B。
所以「密碼管理器」不是要取代 OTP 或 FIDO2,而是先解決大量網站密碼無法安全管理的問題。
02 /密碼存在雲端,為什麼服務商不一定看得到?
密碼管理器通常會把資料放在一個 Vault(密碼保險庫)。它可以跨裝置同步,但關鍵是:在你的裝置加密、在你的裝置解密。伺服器主要接收加密後的資料,而不是每次都代替你打開保險箱。
上方字串只是示意,請不要拿來當真實密碼。這是簡化圖,詳細金鑰階層放在算法附註。
實際上不是「主密碼直接 AES 加密全部資料」
以 Bitwarden 的一般主密碼流程為例,可以把它拆成三層:先用 KDF 把主密碼變成金鑰材料;再用這層材料解開一把受保護的 Vault 對稱金鑰;最後才由 Vault 金鑰解開保存的網站密碼。這種設計叫 Key Hierarchy(金鑰階層)。[01]
伺服器還有登入/營運所需資料,但不等於握有 Vault 明文。
概念示意:實際實作還包含每筆資料的加密金鑰,以及登入用雜湊等程序;不代表所有產品採用同樣金鑰名稱。[01]
KDF、AES、MFA 各自負責什麼?
也別把「零知識」理解成絕對安全。如果電腦已經中毒,而你又把 Vault 解鎖,惡意程式仍可能從畫面、記憶體或填入結果取得資料。雲端儲存被偷,和使用中裝置被控制,是兩個不同的威脅。[01]
| 攻擊者取得 | 哪個機制有幫助? | 哪個機制幫不上忙? |
|---|---|---|
| 網站 A 外洩的帳密 | 每站獨立密碼、MFA | 只把原密碼改一兩個字 |
| 雲端加密 Vault 副本 | 強主密碼、KDF、金鑰設計 | 事後才開的登入 MFA |
| 已解鎖的電腦 | 系統更新、端點防護、鎖定習慣 | 僅靠雲端零知識宣稱 |
| 唯一手機或安全金鑰遺失 | 離線復原碼、備用金鑰、可驗證的備份 | 只在原手機裡留備份 |
03 /Bitwarden 和 1Password,差在哪裡?
我主要會先看這兩個。它們都不是單純把密碼存到雲端,但處理「雲端備份落到攻擊者手上」這種情境時,設計有些不同。
我會先推薦它。免費方案就夠很多人用,也有瀏覽器擴充、桌面版、手機 App 和自動填入。
重視原始碼透明、自架彈性的人可以優先看它;自架要自己負責更新與備份。[01]
如果不介意付費,我也會推薦。介面整合成熟,另外有 Secret Key,降低伺服端資料外洩時單靠猜主密碼解密的風險。
Secret Key 需要跟復原資料一起妥善保管。[04]
兩者都仍然需要強主密碼。1Password 的 Secret Key 不是「第二組要背的密碼」,通常保存在授權裝置及 Emergency Kit;裝置也被入侵時,威脅模型就不同了。[04]
Bitwarden 提供公開原始碼、跨平台 App 與自架彈性;對想看懂金鑰流程、自己控制部署的人很有吸引力。但自架不是神奇的加密升級:TLS、更新、備份、監控和災難復原都要自己負責。[01]
1Password 透過裝置端產生的高熵 Secret Key 與 Account Password 共同保護 Vault,另以 SRP 協定處理登入驗證。這主要是替「服務端資料外洩、攻擊者無法取得你的裝置秘密」增加一道障礙,不代表已授權裝置中毒時還能完全隔離。[04][19]
04 /OTP 那六位數字,究竟怎麼來的?
很多網站叫你「開啟 OTP」,掃一個 QR Code,之後手機就每隔一段時間出現新的六位數字。常見的實作叫 TOTP(Time-based One-Time Password),它不是伺服器每 30 秒傳給手機一個新密碼。[11]
第一次設定時,網站產生一個秘密種子(Seed),透過 QR Code 交給 Authy 等驗證器。之後網站和手機各自用同一份種子、同一個時間窗計算,結果自然會一致。這也說明為什麼手機沒網路,往往還是能產生驗證碼。
同一 T
數字與時間軸純屬原理示意,非可用驗證碼;實際時間容差、HMAC 演算法與位數由服務決定。[11]
TOTP 能阻止「只偷到密碼,沒有手機或種子」的人直接登入。但六位數字沒有和真實網站網域綁定:如果你在假登入頁輸入驗證碼,攻擊者可能立刻轉送給真網站。這是下一節 FIDO2 要解決的問題。[12]
05 /FIDO2、Passkey 為什麼比手輸 OTP 更能防釣魚?
TOTP 的六位數碼是一段可以被轉交的答案。FIDO2/WebAuthn 不一樣:註冊時,安全金鑰或裝置產生一組 Private Key / Public Key;網站只保存 Public Key。登入時,網站發出一次性的 Challenge,驗證器使用 Private Key 簽章,由網站驗證。[13]
攻擊者可能在有效時間內轉送驗證碼。
瀏覽器/驗證器有網域約束;服務端也必須驗證 Origin、Challenge、簽章等條件。
這裡講的是符合規格、正確實作的 WebAuthn 登入。它不能阻止已登入工作階段遭竊,也無法補救網站仍提供的弱式帳號復原途徑。[12][13]
Passkey 是建立在 FIDO 憑證之上的登入體驗,通常讓你不必輸入傳統網站密碼。Passkey 可以留在特定硬體,也可以在支援的生態系中以加密方式同步,這兩種做法的裝置遺失與復原風險不同。
另外,YubiKey 是硬體產品,FIDO2 是協定。同一把相容安全金鑰可能支援傳統 OTP、TOTP 和 FIDO2;不是插了實體金鑰就自動具備 WebAuthn 的釣魚抵抗能力。[21]
06 /TOTP 我還是會跟 Vault 分開放
Authy 依然推薦,並且盡量希望把 TOTP 跟 Vault 分開,分開不只是系統分開,而是最好硬體等級的分開。
這不是因為「兩個 App」聽起來比較安全,而是要避免同一個失陷點同時拿到密碼與第二因素。如果網站密碼和 TOTP 種子都存在同一個已解鎖 Vault,攻擊者一旦能讀取整個 Vault,就可能兩份秘密一起拿到。[20]
分離不能防止所有釣魚攻擊;TOTP 驗證碼仍可能被即時轉送。FIDO2/WebAuthn 則有針對網域的保護。
我會把「分離」分成三個等級
最方便,一般低風險網站未必不合理;但整個 Vault 外洩時兩份秘密可能同時暴露。
例如電腦用 Bitwarden、手機用 Authy。能減少單一 Vault 失陷的連帶影響,但還要看備份帳號是否共享。
主要信箱、雲端、金融或管理帳號,能用 FIDO2 就先用;準備第二把金鑰以免遺失後無法復原。
適合想用手機獨立管理 TOTP 的人。備份可以加密同步,但備份密碼不要只放在同一個 Vault。[06]
要注意:Authy 的 Windows/macOS/Linux 桌面版已在 2024 年 3 月停止支援,現在以手機 App 為主。若設好備用裝置,官方建議完成新增後關閉允許新裝置加入的 Multi-Device 選項。[08] [07]
Authy 的備份密碼不會由 Twilio 代你保存或恢復。因此如果開了備份同步,備份密碼必須自己能找得到;別把它和 Vault 的唯一復原方式鎖在同一個地方。關掉 Multi-Device 的新增權限後,也要確認自己已經留有有效的備用裝置或復原途徑。[06][07]
07 /自動填入很方便,但它也有自己的安全邊界
自動填入,是一個不錯的方案,目前很多 app 會讀取你的剪貼簿。
現代 Android/iOS 已對剪貼簿讀取加入權限、提示或背景限制,不是每個 App 都能隨時偷看。但把密碼放進剪貼簿,仍會增加暴露途徑;若可以使用系統整合的自動填入,就不必每次複製貼上。[10][17]
管理器怎麼知道「現在是哪一個網站」?
以瀏覽器擴充功能為例,密碼管理器通常會拿目前頁面的 URL/URI,和 Vault 中保存的網址做比對。Bitwarden 預設的 Base domain 適合大多數網站,但也能指定 Host 或 Exact,減少在不想填入的子網域顯示登入資料。[18]
https://login.example.com/
example.com 的不同子網域可能一起匹配。
login.example.com 這個主機名稱。
不過,「有出現自動填入建議」不等於保證網站可信。網站本身如果遭入侵、存在惡意欄位,仍可能讀取已填入的密碼。Bitwarden 會對某些不可信 iframe 提醒或阻擋,因此我會關閉「網頁載入時就自動填入」,需要時再由快捷鍵或手動操作觸發。[09]
手機上的自動填入通常會透過作業系統提供的服務,以及 App 身分/關聯網域等資訊協作;它不一定具有桌面瀏覽器同樣精細的 URL 路徑判斷。再安全的自動填入也不會讓惡意 App 自動變安全。
08 /真的要開始用,我會照這個順序設定
-
01
設定一組獨立、長且難猜的主密碼與任何網站都不重複;可以用隨機產生的多詞密碼短語,而非生日+固定規則。
-
02
把常用網站改成每站唯一密碼使用管理器產生長的隨機密碼;先處理信箱、雲端、金融與曾重複使用密碼的網站。
-
03
登入 Vault 本身也加第二因素支援時優先用 FIDO2 安全金鑰;否則使用獨立手機上的 TOTP,別把唯一 MFA 秘密只放在待登入的同一 Vault。
-
04
使用自動填入,但保留確認動作檢查網站網域/App;關閉一載入即自動填入;敏感服務可把 URI 比對改成 Host 或 Exact。
-
05
替根帳號準備獨立復原途徑主要信箱、密碼管理器、Passkey 同步帳號,都不要只有一條會互相依賴的復原鏈。
-
06
備份加密匯出檔,並實際測試恢復Bitwarden 可考慮密碼保護的 encrypted JSON;附件另處理,不能把普通 ZIP 當成加密備份。[16]
-
07
保持系統更新、定時鎖定 Vault減少不必要的瀏覽器擴充套件;不要在不可信共用裝置上解鎖 Vault。
09 /想繼續看技術的話:把算法展開
上面先說「為什麼要這樣做」。以下是實際金鑰流程、公式、協定驗證與例外條件;想研究哪一段,再打開就好。
01 · Bitwarden 金鑰階層:Master Key 到 Vault 明文
一般使用主密碼登入的 Bitwarden 帳號,客戶端以主密碼和帳號信箱等輸入進行 KDF,取得 Master Key。再經 HKDF 展開得到 Stretched Master Key,用它解開從伺服器取回的 Protected Symmetric Key,得到 User Symmetric Key。資料解密在客戶端執行。這裡展示的是概念流程,省略個別項目加密金鑰與其他登入方式。[01]
Master Password + account salt
↓ KDF (PBKDF2 或 Argon2id)
Master Key
↓ HKDF(展開不同用途的金鑰材料)
Stretched Master Key
+ 伺服器保存的 Protected Symmetric Key
↓ 在本機解開
User Symmetric Key
↓ 解開 Vault 項目相關金鑰與密文
Vault 明文(只在授權裝置需要時使用)
注意區分「驗證登入」與「解密 Vault」:登入通常還會使用可供服務端驗證的衍生雜湊及 MFA;解密則是拿到真正的對稱金鑰。改主密碼、調 KDF 參數、輪替 Vault 加密金鑰是不同作業,不能認為改了密碼就讓攻擊者已保存的舊密文瞬間失效。[22]
02 · PBKDF2 與 Argon2id:鹽值、迭代、記憶體成本
KDF 的輸入是人類容易記憶、熵可能不足的主密碼;用鹽值(salt)與昂貴的計算,讓攻擊者對每個猜測都必須重新付費。Salt 通常不需要保密,目的是讓相同密碼在不同帳號上得到不同的輸出,並提高預先計算表的重複利用難度。
PBKDF2-HMAC-SHA256(P, salt, c, dkLen) P = 主密碼 salt = 非秘密的鹽值 c = 迭代次數 dkLen = 需要輸出的金鑰長度 Argon2id(P, salt, m, t, p) m = 記憶體成本 t = 時間/迭代成本 p = 平行度
Bitwarden 文件中的預設參考:PBKDF2-HMAC-SHA256:600,000 iterations;Argon2id:32 MiB、6 iterations、parallelism 4。PBKDF2 主要增加重複計算;Argon2id 同時要求記憶體,讓高平行猜測不那麼便宜。600,000 不能直接和 6 比較,因為工作模型完全不同。[02]
簡化成本模型:總猜測時間 ≈ 猜測次數 × 單次猜測成本 ÷ 有效並行量。但 GPU、記憶體頻寬、KDF 參數與硬體配置會大幅改變結果,不能直接用解鎖秒數換算出可靠破解時間。長且獨立的主密碼仍是第一條防線。
03 · AES-CBC/HMAC 與 AES-GCM,差別不是數字大小
04 · TOTP 的公式:HMAC、時間窗與動態截斷
TOTP 基於 HOTP。網站和驗證器共享一個隨機秘密種子
K,把目前時間映射成計數器 T,再以 HMAC
的結果轉成短數字。[11]
T = floor((UnixTime − T₀) / X) H = HMAC(K, encode_8_byte_big_endian(T)) OTP = DynamicTruncate(H) mod 10^d K = 共享秘密種子 T₀ = 基準時間(常見 Unix epoch) X = 每個時間窗的秒數(常見 30) d = 輸出位數(常見 6)
RFC 6238 支援 HMAC-SHA-1/256/512 方案,實際服務的
seed、位數和時間窗必須相容。六位碼總共只有
10^6
種可能,因此服務端需要登入失敗速率限制,並處理時間誤差與重放檢查;不是把
30 秒內任何無限次猜測都視為合理。
QR Code 內往往包含秘密種子或可還原種子的設定 URI;不要把它當一般登入 QR Code 分享到群組。拿到 K 的人可以在後續時間窗自行算出驗證碼。
05 · WebAuthn 驗證到底檢查哪些欄位?
註冊(registration)時,驗證器為特定 RP 建立公私鑰對,網站保存 Public Key 與 Credential ID。登入(authentication)時,網站下發不可預測的 Challenge;瀏覽器/驗證器產生 Assertion,伺服端驗證。[13]
註冊:
Authenticator → (private key, public key)
Server ← public key + credential ID
登入:
Server → challenge
Authenticator → signature over
authenticatorData || SHA256(clientDataJSON)
Server checks:
challenge / type / Origin
rpIdHash / UP・UV flags(依政策)
signature / credential binding
Origin 表示呼叫 WebAuthn API 的網站來源;RP ID 是憑證被允許使用的依賴方範圍。假站不能隨意冒用真站的 RP ID 或替真站取得有效斷言;服務端也必須確實檢查,不可只驗簽章後忽略上下文。
「防釣魚」不等於「防所有帳號接管」:已登入的 Session Cookie、惡意瀏覽器擴充套件或弱式復原流程仍可能成為其他入口。[12]
06 · Passkey 是什麼?同步型與硬體綁定型的差異
07 · 1Password Secret Key、SRP 與金鑰威脅模型
1Password 在裝置上產生具有約 128 bits 熵的 Secret Key,與 Account Password 一起參與帳號加密金鑰的保護。它不是帳號序號,也不是第二個要背的密碼;Secret Key 會保存在授權裝置及適當的 Emergency Kit。[04]
SRP(Secure Remote Password) 用於登入身分驗證,不等於 Vault 的資料加密;其設計目標是讓服務端能進行密碼證明,而不必接收使用者輸入的原始 Account Password。[19]
攻擊者只拿到伺服器加密資料時,缺乏 Secret Key 是額外的離線攻擊障礙;但如果他同時控制已授權裝置、取得 Secret Key 或復原資料,就不能照搬「純伺服器外洩」的安全推論。
08 · Autofill:URI 比對、iframe 和端點風險
Bitwarden 的 Base domain 會參考有效註冊網域;Host 約束主機名稱;Exact 要求整個 URI 完全相符。敏感子網域有時應改用 Host/Exact,但 Exact 可能因路徑或 query string 變動而失效。Android、iOS 的可比對資訊還可能受到 OS API 限制。[18]
Bitwarden 的「Autofill on page load」預設關閉;官方也提醒受攻擊的網站可能利用這個便利性。使用者手動觸發、檢查網址、避免可疑 iframe 都有意義;但一旦憑證真的填進惡意的頁面欄位,光靠 URL 配對無法阻止網頁腳本讀取當前欄位。[09]
剪貼簿清除計時只能降低殘留時間,不應被視為防止所有剪貼簿讀取的安全沙箱。
09 · Vault 備份與復原:encrypted JSON、附件與死結
跨裝置同步主要維持目前資料一致,不等於你能在帳號被鎖、設備都遺失時取回舊資料。以 Bitwarden 為例,Password protected encrypted JSON 用另設密碼保護且可匯入別的帳號;Account restricted 則依賴原帳號的加密金鑰,不宜當作唯一的跨帳號災難備援。[16]
一般的加密 JSON 匯出不含檔案附件。含附件的 ZIP 匯出還應另外使用加密容器保護,不能因為副檔名是 ZIP 就以為已加密。復原資料必須在 Vault 無法登入時也拿得到。
最簡單的實際演練:確認離線保存的復原碼能找到、備份檔能解密、測試環境能匯入、附件另行檢查。必要時先在隔離環境操作,不要為測試而在共用電腦輸入真的主密碼。
↗ /參考來源
官方文件、標準規格與事件說明。產品功能與設定名稱以實際版本為準。
[01] Bitwarden · Security Whitepaper — Vault 金鑰階層
[02] Bitwarden · Encryption Key Derivation — PBKDF2 / Argon2id
[03] Bitwarden · Encryption Protocols — AES-CBC / HMAC
[04] 1Password · About your Secret Key
[05] 1Password · Security model
[06] Twilio · Authy backups & sync
[07] Twilio · Authy Multi-Device
[08] Twilio · Authy Desktop EOL — 2024-03-19
[09] Bitwarden · Autofill from browser extensions
[10] Android Developers · Secure Clipboard Handling
[12] NIST · SP 800-63B-4
[13] W3C · Web Authentication Level 3
[14] Google Chrome Help · Use saved passwords in other apps
[15] LastPass · Security incident update — 2022 年事件後續說明
[16] Bitwarden · Export Vault Data
[17] Apple Developer · UIPasteControl — iOS 剪貼簿存取提示
[18] Bitwarden · Form URIs for Autofill — Base domain/Host/Exact
[19] 1Password · Secure Remote Password — SRP 登入驗證
[20] Bitwarden · Authenticator — 本機 TOTP 與 Vault 同步的差異
[21] Yubico · Authenticator — 硬體 TOTP 與 FIDO2 的區別
[22] Bitwarden · Encryption Key Rotation — 主密碼變更與金鑰輪替
[延伸] iThome 鐵人賽 · 密碼學系列

留言與討論
正在連線到留言服務…