你可能看過那種小提示寫著「使用 Face ID 登入」或「使用通行金鑰」,而不是傳統的密碼欄位。那就是通行金鑰(passkey)。而且,不,它不只是把密碼藏在你的指紋後面而已。

最好的密碼,就是你從來不需要輸入的那個。

密碼的問題

密碼是一種秘密, 必須記住它,而網站 必須儲存它(理想上是雜湊後的)。問題在於,這套系統完全依賴兩個薄弱點:

  • 你,因為想不出新密碼而把同一組密碼到處重複使用。
  • 網站,因為它可能被駭,密碼資料庫也可能外洩。

再加上釣魚攻擊:一個完美模仿真實網站的假網站,可以在你毫不知情的情況下竊取你的密碼。而這不只是小問題:正如 Verizon DBIR 報告 每年提醒我們的,社交工程、釣魚攻擊和遭竊的憑證,至今仍是全球駭客入侵的主要原因之一,和軟體漏洞並列。

Verizon DBIR 報告中關於駭客入侵原因的摘錄

<small>來源:Data Breach Investigations Report, Verizon</small>

即使有密碼管理器和雙重驗證(2FA),根本上的弱點仍然存在:一個你可能會不小心分享出去的秘密。

什麼是通行金鑰?

通行金鑰是基於非對稱加密,如果你曾經為了連線到伺服器而產生過金鑰對,原理其實跟 SSH 一樣。

當你為某個網站建立通行金鑰時:

  1. 你的裝置(手機、電腦、安全性權杖)會產生一組金鑰對:私鑰與公鑰。
  2. 私鑰絕不會離開你的裝置。它會儲存在安全晶片中:iPhone/Mac 上的 Secure Enclave、Windows 上的 TPM,或直接存在像 YubiKey 這類 USB 金鑰的晶片裡。
  3. 另一方面,公鑰會傳送給網站並儲存在伺服器上。

登入時,網站會送給你一個挑戰值(隨機數字),你的裝置會用私鑰對它簽章,網站再用公鑰驗證簽章。如果相符,你就通過驗證。

沒有任何秘密會在網路上傳輸,只有簽章。這在 W3C WebAuthn 規格 裡寫得清清楚楚:沒有東西可偷,也沒有東西可釣魚。

為什麼更安全

密碼 通行金鑰
共用秘密,每次登入都會傳送 不會傳送任何秘密,只傳送簽章
可在多個網站重複使用 每個網站都唯一,並綁定網域
易受釣魚攻擊 抗釣魚(綁定到精確的網域)
伺服器遭入侵時可能外洩 伺服器只儲存公鑰,對攻擊者沒有用
必須記住,或透過密碼管理器管理 透過生物辨識或本機密碼解鎖

關鍵在於:通行金鑰會綁定到建立它的網域。如果你去的是 paypa1.com 而不是 paypal.com,你的裝置甚至不會提供通行金鑰。這是瀏覽器/作業系統在驗證,不是你。Google 解釋得很清楚:不同於密碼,通行金鑰在密碼學上與建立它的網站綁定,因此不可能被攔截或在假網站上重複使用。它們天生就能抵抗釣魚攻擊,不是因為使用者很小心,而是設計如此。

內部原理:WebAuthn 與 FIDO2

從技術上來說,通行金鑰是建立在 WebAuthn(W3C)標準之上,而它又是更廣泛的 FIDO2 標準的一部分,該標準由 FIDO 聯盟推動(成員包括 Google、Apple、Microsoft 和 Yubico)。這就是瀏覽器透過 JavaScript 提供,用來建立與使用憑證的 API。

使用者、瀏覽器與伺服器之間的 WebAuthn 註冊流程圖

<small>註冊流程圖,依據 W3C WebAuthn 規格</small>

在客戶端建立通行金鑰大致如下:

const credential = await navigator.credentials.create({
  publicKey: {
    challenge: new Uint8Array(32), // 由伺服器提供
    rp: { name: "My Super Site", id: "mysupersite.com" },
    user: {
      id: new Uint8Array(16),
      name: "[email protected]",
      displayName: "Thomas",
    },
    pubKeyCredParams: [{ alg: -7, type: "public-key" }], // ES256
    authenticatorSelection: { userVerification: "required" },
  },
});

而使用既有的通行金鑰登入則如下:

const assertion = await navigator.credentials.get({
  publicKey: {
    challenge: new Uint8Array(32), // 由伺服器提供
    userVerification: "required",
  },
});

伺服器會產生 challenge,瀏覽器負責所有生物辨識與解鎖流程,並把要驗證的簽章回傳給你。在伺服器端,像 Node.js 裡的 @simplewebauthn/server 這類函式庫會處理大部分驗證工作。

如果我把手機弄丟了怎麼辦?

這是最常讓人卡住的問題;如果這個主題也很符合你的情境,我之前已經寫過一篇關於手機被偷後雙重驗證的麻煩,而同樣的「單一故障點」原則也適用於通行金鑰。自 2022 年起,Apple、Google 和 Microsoft 都加入了通行金鑰同步

  • 在 iOS/macOS 上,透過你的 iCloud 鑰匙圈 同步。
  • 在 Android/Chrome 上,透過你的 Google 帳戶 同步,使用 Google 密碼管理工具,而且會端對端加密所有內容。
  • 在 Windows 上,透過 Windows Hello,不過那裡的跨裝置同步比 Apple 或 Google 還更受限。

所以如果你弄丟手機,但在新裝置上重新取得 iCloud 或 Google 帳戶的存取權,通行金鑰也會一併還原。你也可以把實體安全金鑰(YubiKey)當作備援,它不會同步,但可在任何相容裝置上使用——這和傳統 2FA 的建議完全一樣:不要把所有雞蛋放在同一個籃子裡。

今天要怎麼使用?

越來越多服務已經支援它:Google、Apple、GitHub、Microsoft、PayPal、Amazon、X……Google 甚至更進一步,將個人帳戶的預設驗證方式改為通行金鑰。你通常可以在帳戶的安全性設定中找到,名稱可能是「存取金鑰」或「通行金鑰」。

一般流程如下:

  1. 前往服務的安全性設定。
  2. 點選「新增存取金鑰」或「建立通行金鑰」。
  3. 瀏覽器或作業系統會要求你使用 Face ID、Touch ID、Windows Hello 或手機密碼進行確認。
  4. 就這樣完成了。下次登入時,你就不需要密碼了。

如果你想把通行金鑰管理在 OS 鑰匙圈以外的地方(例如你會在多個不同平台間切換時很有用),Proton Pass 也能建立與儲存它們——同樣採用端對端加密——並與你的密碼放在同一個地方。

結論

問題 答案
它基於什麼? 非對稱加密(私鑰/公鑰對)
密碼會在網路上傳輸嗎? 不會,從不
能防釣魚嗎? 可以,天生就能(綁定網域)
技術標準 WebAuthn / FIDO2
裝置遺失 可透過 iCloud/Google 同步恢復,或使用實體備份金鑰

通行金鑰不只是「把密碼藏在指紋後面」,它代表的是整個驗證模型的轉變:不用記、也偷不到。如果某個服務提供你建立通行金鑰的選項,就用吧——它比你現在的密碼更安全,也更快。

本文中的 Proton Pass 連結為聯盟行銷連結;如果你透過此連結註冊,我可能會獲得佣金,且不會增加你的任何額外費用。這有助於我支付主機與網域費用。感謝你的支持!


原文出處:https://dev.to/thomasbnt/passkeys-explained-simply-52jk


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝11   💬1   ❤️6
325
🥈
我愛JS
📝2   💬6   ❤️3
113
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登