更新紀錄(僅初版,2026年07月29日 發布)
- 初次發布
引用本文(DOI(已登錄存檔): 10.5281/zenodo.22175454)
以下 DOI 指向先前登錄的存檔,內容可能與目前正文不同。引用目前正文時,請使用本頁網址。
Go Komura(2026)。〈Passkey 為什麼安全 ── 圖解運作機制、同步與遺失時的注意事項〉。小村軟體有限公司。 https://comcomponent.com/zh-TW/blog/passkey-why-secure/
- DOI(已登錄存檔)
- 10.5281/zenodo.22175454
- DOI(上次登錄版本)
- 10.5281/zenodo.22175455
「可以用指紋登入,所以很安全」。Passkey 有時會被這樣介紹,但安全性的核心並不是指紋或臉部本身,而在於不把私密金鑰交給登入的對象,只用簽章證明自己持有那個網站專用的金鑰。1
不過,如果理解成「用了 Passkey 就絕對不會被盜用」「私密金鑰一定不會離開手機」,在同步與遺失時就會做出錯誤的判斷。登入機制變強,和裝置、復原手段以及登入後的工作階段也自動變安全,是兩回事。
本文從與密碼的差異出發,圖解註冊與登入的流程,依序整理它對網路釣魚有抵抗力的原因、同步型與裝置固定型的差異,以及遺失裝置時的處理。後半段則討論導入自家 Web 服務或 Windows 業務系統時的確認要點。
1. Passkey 安全的理由有三個
Passkey 是可以取代密碼用來登入的以公開金鑰加密為基礎的認證資訊。註冊時產生的金鑰對中,私密金鑰由使用者端保管,公開金鑰則註冊到服務端。在 Web 上的註冊與驗證使用名為 WebAuthn 的標準 API。12
| 安全性的依據 | Passkey 改變了什麼 | 由此推論不出的事 |
|---|---|---|
| 不把私密金鑰交給登入的對象 | 即使只有公開金鑰外洩,攻擊者也做不出正確的簽章 | 並不表示伺服器的資料外洩就變得無害 |
| 每一次登入嘗試都驗證回應 | 檢查與新挑戰值綁定的簽章,防止重複使用過去的回應 | 並不表示可以省略挑戰值的管理 |
| 限制認證資訊的使用對象 | 無法從無關的假網域使用真網站專用的 Passkey | 並不表示詐騙與濫用帳號復原流程也會隨之消失 |
flowchart TB
accTitle: Passkey 改變的三個驗證弱點
accDescr: 對秘密的交付、回應的重複使用、使用對象的認錯,分別以不同的機制來因應。
A["以 Passkey 登入"] --> B["不交出私密金鑰,只回傳簽章"]
A --> C["比對並消耗挑戰值"]
A --> D["確認 RP ID 與來源"]
B --> E["只有公開金鑰無法偽造簽章"]
C --> F["不讓過去的回應被重複使用"]
D --> G["不讓無關的假網站拿來使用"]
圖1:Passkey 的強度,在於把加密、一次性的要求與使用對象的限制組合起來。
本文所說的「不傳送私密金鑰」,傳送的對象指的是所登入服務的伺服器。在同步型 Passkey 中,另有一條把私密金鑰加密後保管與複製的路徑。把這裡分開來看,就能解開「既然要同步到雲端,怎麼還說不傳送秘密」這個疑問。
此外,伺服器除了公開金鑰之外,還會保存認證資訊的識別碼、與帳號的對應關係、工作階段資訊等。「只有公開金鑰無法冒用身分」和「資料庫不必保護」並不是同一件事。2
圖中實線表示始終成立的關係,虛線表示附帶條件的關係(成立條件寫在詳細頁面中各關係的說明中)。關係的完整清單(共 38 條,附依據與可信度)以及主要概念的定義,彙整在知識地圖詳細頁面(日文)。資料:JSON-LD / Turtle
2. 長密碼與一次性驗證碼還留下什麼問題
一般的密碼驗證會把使用者輸入的密碼,透過 TLS 保護的通訊傳送到伺服器,由伺服器與已儲存的雜湊值等進行比對。適當的加鹽雜湊與足夠的計算成本,會讓儲存資料外洩後反覆猜測的攻擊變得困難。隨機、夠長且不重複使用的密碼同樣有意義。3
如果在多個服務上重複使用同一組密碼,攻擊者就可能把從一處外洩的帳號與密碼組合拿去其他網站試用,也就是「撞庫攻擊」,讓災情擴散到其他帳號。即使密碼很長,只要重複使用就擋不住這種擴散。4
即使如此,使用者仍然可能把正確的密碼交給錯誤的對象。只要在攻擊者準備的網站上輸入了真密碼,即使那個網站的 TLS 憑證本身沒有問題,輸入的值也會送到攻擊者手上。這不是 TLS 被攻破,而是搞錯了正在安全通訊的對象。
sequenceDiagram
accTitle: 對假網站的輸入光靠 TLS 擋不住
accDescr: 使用者輸入到假網站的密碼與驗證碼,即使走加密通訊,也一樣會送到假網站的經營者手上。
participant U as 使用者
participant P as 假網站
participant S as 真正的服務
U->>P: 輸入真正的密碼
P->>S: 中繼所輸入的密碼
S-->>P: 要求追加驗證
P-->>U: 要求一次性驗證碼
U->>P: 輸入驗證碼
P->>S: 趁有效期間內中繼驗證碼
S-->>P: 驗證成功後發出工作階段
圖2:這是把密碼與驗證碼即時中繼的 AiTM 型網路釣魚的概略流程。
TOTP 是驗證應用程式與伺服器共用同一個種子,依時間產生驗證碼的方式。並不是每次登入都把種子本身傳送出去。不過,使用者輸入的驗證碼並未與正規網站的網域綁定,因此在有效期間內仍有被假網站中繼的空間。簡訊驗證碼同樣有「可以輸入到假網站」這個問題。3
這並不是說多重要素驗證沒有意義。比起只靠密碼的驗證,能擋下的攻擊確實變多了。在這個前提上,面對連手動輸入驗證碼都要下手的攻擊,往 FIDO/WebAuthn 這類具抗網路釣魚能力的驗證前進才有意義。5
用密碼管理員產生強密碼、只對正確的網域自動填入,也是有效的對策。但那組密碼仍然可以被複製、貼到別的輸入欄位。Passkey 的不同之處在於,使用者無法單靠自己的操作解除這道使用對象的限制。
3. 註冊與登入時,來回傳送的究竟是什麼
註冊時產生金鑰對,並與帳號綁定
處理 Passkey 的角色大致有三個:服務端的 RP(Relying Party,信賴方)、提供 WebAuthn 的瀏覽器與作業系統,以及負責產生與使用金鑰的驗證器。驗證器包含與作業系統功能或認證管理員搭配運作的,以及外接的 FIDO2 安全金鑰等。臉部或指紋的比對,是為了許可這項使用而進行的處理。26
sequenceDiagram
accTitle: Passkey 註冊的流程
accDescr: 依註冊要求產生金鑰對,服務驗證註冊回應後,把公開金鑰與認證資訊 ID 綁定到帳號上。
participant S as 服務
participant B as 瀏覽器與作業系統
participant A as 驗證器
S->>B: 挑戰值與帳號資訊
B->>B: 確認使用對象
B->>A: 要求建立認證資訊
A->>A: 本人確認與產生金鑰對
A-->>B: 公開金鑰與認證資訊 ID 等
B->>S: 傳送註冊回應
S->>S: 驗證註冊回應
S->>S: 把認證資訊註冊到帳號
圖3:註冊的不只是公開金鑰,而是包含識別碼與驗證用資料的回應。私密金鑰不會傳送給登入的對象。
credential ID(認證資訊 ID)是用來識別「是哪一把 Passkey」的值。伺服器會把它與公開金鑰及帳號對應起來儲存。要把新的 Passkey 加到既有帳號時,先用既有方式確認對方確實是該帳號的使用者,必要時重新驗證。不可以只憑瀏覽器送來的使用者名稱就決定要註冊到哪個帳號。67
一般來說,在不同服務或不同帳號註冊時會另外產生新的金鑰對,因此使用者不必做出相當於「重複使用密碼」的行為。不過,這套機制並不能阻止對方以電子郵件位址等其他資訊比對出使用者,並不代表「用了 Passkey 就會匿名」。
登入時回傳的是針對本次要求的簽章
登入時,伺服器會發出難以預測的亂數,也就是挑戰值。驗證器用私密金鑰做出簽章,再由瀏覽器把它回傳給伺服器。伺服器以已註冊的公開金鑰驗證,並確認這是不是對本次所發出要求的正確回應。6
sequenceDiagram
accTitle: Passkey 登入的流程
accDescr: 驗證器做出與本次要求綁定的簽章,伺服器驗證簽章與挑戰值、使用對象以及帳號。
participant S as 服務
participant B as 瀏覽器與作業系統
participant A as 驗證器
S->>B: 未使用的挑戰值與 RP ID
B->>B: 確認使用對象是否妥當
B->>A: RP ID 與資料的雜湊
A->>A: 以生物特徵或 PIN 確認
A->>A: 用私密金鑰簽章
A-->>B: 驗證器資料與簽章
B->>S: 認證資訊 ID 與驗證回應
S->>S: 驗證回應與帳號
S-->>B: 只有成功時才發出工作階段
圖4:登入的回應是「持有私密金鑰的證明」,而不是私密金鑰本身。
更精確地說,驗證時的簽章對象是下列資料。|| 表示位元組序列的串接。8
簽章對象 = authenticatorData || SHA-256(clientDataJSON)
clientDataJSON:
type 驗證時為 webauthn.get
challenge 伺服器發出的挑戰值
origin 呼叫端的來源
authenticatorData:
rpIdHash RP ID 的 SHA-256 雜湊
flags 使用者存在與使用者驗證等的結果
signCount 簽章計數器
「對挑戰值簽章」是為了掌握全貌而簡化的說法。實際上使用對象與驗證器的狀態,也都與簽章的驗證有關。另外,並不是由驗證器去讀取網頁來判斷來源,而是接收瀏覽器蒐集好的用戶端資料雜湊,這樣的分工也很重要。
flowchart TB
accTitle: 驗證時與簽章綁定的資料
accDescr: 把包含挑戰值與來源的用戶端資料雜湊,與包含 RP ID 雜湊等內容的驗證器資料串接後簽章。
A["挑戰值與來源等"] --> B["clientDataJSON 的雜湊"]
C["RP ID 的雜湊與旗標等"] --> D["authenticatorData"]
B --> E["串接驗證器資料與雜湊"]
D --> E
E --> F["用私密金鑰簽章"]
圖5:不只是挑戰值,使用對象與驗證器的狀態也都牽涉到簽章的驗證。
過去的簽章之所以無法重複使用,並不是因為簽章本身會隨時間消失,而是因為伺服器把挑戰值與登入嘗試綁定、設定期限,並且不再接受已經用過的要求。光是公開金鑰的簽章驗證成功,還不足以構成允許登入的條件。
4. 為什麼在幾可亂真的假網站上也用不了
RP ID 與來源的角色不同
RP ID 是決定認證資訊範圍的網域名稱,通常會指定成 example.com 這樣的形式。另一方面,來源是 URL scheme、主機與連接埠的組合。舉例來說,可以是 https://login.example.com 為來源、example.com 為 RP ID 的組態。9
在一般的網域關係驗證中,可以從 login.example.com 的頁面指定 RP ID 為 example.com。但是無法從無關的 examp1e.com 頁面指定 example.com,去使用真網站專用的 Passkey。判斷依據不是外觀像不像,而是由瀏覽器驗證使用對象之間的關係。
flowchart TB
accTitle: RP ID 對認證資訊使用對象的限制
accDescr: 具備正規網域關係的頁面與無關的假網站,在要求真正的 RP ID 時,瀏覽器的判斷並不相同。
A["把 RP ID 指定為 example.com"] --> B{"呼叫端是誰"}
B -->|"login.example.com"| C["符合網域關係的條件"]
B -->|"examp1e.com"| D["因為是無關的網域而拒絕"]
C --> E["用對應的 Passkey 繼續驗證"]
E --> F["伺服器也驗證是否為允許的來源"]
D --> G["用不了真網站專用的 Passkey"]
圖6:瀏覽器的使用對象限制與伺服器的來源驗證,兩者一起撐起抗網路釣魚的能力。
伺服器端也要驗證與簽章一起回傳的 origin 是否為已允許的來源、rpIdHash 是否為預期 RP ID 的雜湊。不可以把用假網站自己的 RP ID 產生的金鑰,或是來自未允許來源的回應,當成真正帳號的驗證而接受。8
另外,WebAuthn Level 3 還有 Related Origin Requests,可讓服務端在明確關聯過的其他來源上使用相同的 RP ID。因此「主機名稱不完全相同就一定用不了」這種說法也不精確。重要的是把認證資訊的使用範圍,關在服務所認可的範圍內。即使使用關聯來源,也不是要把伺服器的允許清單無限制地放寬。9
「抗網路釣魚」不等於能抵抗所有詐騙
到這裡的說明,都建立在瀏覽器、作業系統與驗證器可信,且伺服器有做必要驗證的前提上。正規網站遭入侵、裝置上的惡意軟體,或是薄弱的帳號復原程序,並不是光靠 WebAuthn 就能解決的。
也可能被假網站以「這裡不能用 Passkey,請輸入密碼與簡訊驗證碼」誘導,轉而使用另一條登入路徑。Passkey 擅長的是避免把真正的認證資訊交到假網站手上,並不代表使用者從此完全不需要留意。5
5. 指紋、臉部與 PIN 不是給伺服器的密碼
使用 Passkey 時之所以會要求指紋或臉部,是為了確認使用私密金鑰的操作,是否經過該裝置的正當使用者同意。這項處理稱為使用者驗證(User Verification,UV)。WebAuthn 的驗證回應不會夾帶指紋影像或臉部特徵值傳送給登入的對象。12
flowchart TB
accTitle: 裝置上的本人確認與服務端的簽章驗證
accDescr: 指紋、臉部與 PIN 用於在使用者端許可金鑰的使用,服務端確認的不是生物特徵資訊,而是簽章與驗證結果。
A["以指紋、臉部或 PIN 確認"] --> B["驗證器許可私密金鑰的使用"]
B --> C["產生帶簽章的驗證回應"]
C --> D["服務以公開金鑰驗證"]
D --> E["同時確認所要求的使用者驗證結果"]
圖7:裝置的解鎖與對服務的驗證會互相搭配,但伺服器並不會去比對指紋或 PIN。
也許有人會覺得,既然 PIN 也能用,那不就跟密碼一樣嗎。差別在於這個 PIN 是拿去和什麼比對。這裡的 PIN 是用來許可驗證器的使用,並不是網站保有全體使用者份、每次登入都要收下的密碼。在適當的驗證器上,還會有輸入錯誤的次數限制等機制運作。3
不過,如果裝置被偷、連解鎖方式都被對方知道,攻擊者能夠使用 Passkey 的風險就會升高。並不是換成臉部辨識之後,裝置的密碼就可以設得很簡單。另外,表示觸碰畫面等動作的使用者存在(User Presence,UP),和以生物特徵或 PIN 進行的 UV 是不同的旗標。實作端要要求必要的 UV,並在回應中一併確認。
6. 同步型與裝置固定型,要守的地方不一樣
Passkey 分成會在裝置之間同步的,以及與特定驗證器綁定的。兩者都是在不把私密金鑰交給登入對象的前提下完成驗證,但金鑰的保管、複製與復原方式並不相同。10
| 觀點 | 同步型 Passkey | 裝置固定型 Passkey |
|---|---|---|
| 私密金鑰的處理 | 透過保管庫複製到各裝置之間 | 保留在特定的驗證器中,不進行同步 |
| 代表例子 | 儲存到 iCloud 鑰匙圈、Google 密碼管理員等 | FIDO2 安全金鑰、儲存在 Windows Hello 本機容器中的認證資訊等 |
| 換機或故障時 | 滿足同步與保管庫的復原條件,就能在別的裝置上使用 | 需要另外註冊的金鑰或帳號復原手段 |
| 管理上的重點 | 同步帳號、保管庫的解鎖條件、參與的裝置 | 驗證器的保管、備用金鑰、失效程序 |
| 硬體保護 | 依產品與裝置而異 | 光憑「固定型」這個分類,決定不了保護的強度 |
flowchart TB
accTitle: 同步與登入是兩條不同的路徑
accDescr: 同步型透過加密的保管庫複製金鑰,但不論同步型或固定型,送給登入對象的都是驗證回應。
V["加密過的同步保管庫"] <-->|"同步與復原"| A["裝置 A 的同步型 Passkey"]
V <-->|"同步與復原"| B["裝置 B 上同一把 Passkey"]
A -->|"帶簽章的回應"| S["登入對象的服務"]
B -->|"帶簽章的回應"| S
K["固定型的驗證器"] -->|"帶簽章的回應"| S
圖8:把複製私密金鑰的同步路徑,和對服務登入的路徑分開來看,就能理解兩者的差異。
在 Apple 與 Google 的機制中,會用端對端加密保護要同步的 Passkey。其設計並不是讓服務提供者可以直接讀取雲端上的儲存資料而取得私密金鑰。1112
另一方面,要在新裝置上復原,除了登入同步帳號之外,有時還需要舊裝置的螢幕鎖定或保管庫 PIN 等條件。具體條件會因產品與設定而異。既不能說「只要有雲端帳號的密碼就能還原全部 Passkey」,也不能說「只要拿回雲端帳號就一定能還原」。1113
在同步型中,如果連保管庫的解鎖與復原手段,甚至參與的裝置都遭到入侵,對多個服務的影響就可能擴大。同步帳號的多重要素驗證、夠強的裝置鎖定,以及復原目標的管理都很重要。若服務有支援,也可以考慮用實體安全金鑰來保護。不過,如果連復原用的金鑰都只放在同一台裝置或同一個保管庫,就會變成一次全失去的組態。
組織的保證等級也需要留意。在 NIST SP 800-63B-4 中,可同步的驗證器只要滿足條件即可用於 AAL2,但不得用於不允許匯出私密金鑰的 AAL3。反過來說,裝置固定型也不會自動就是 AAL3,仍必須滿足硬體保護等其餘要求。1415
用 QR Code 搭配手機的方式和同步不一樣
也有用手機掃描電腦上顯示的 QR Code,再用那支手機的 Passkey 登入的方式。FIDO 的跨裝置驗證會透過藍牙等確認雙方距離接近,並在手機端完成驗證。這並不是把手機的私密金鑰複製到電腦上的操作。161
flowchart TB
accTitle: 用手機的金鑰登入另一台電腦的流程
accDescr: 用手機掃描電腦上的 QR Code,經過距離確認與手機上的使用者驗證後完成驗證。這個流程不會把私密金鑰複製到電腦。
A["在電腦的登入畫面顯示 QR Code"] --> B["用手機掃描 QR Code"]
B --> C["確認裝置彼此的距離接近"]
C --> D["在手機上完成使用者驗證與簽章"]
D --> E["服務驗證驗證回應"]
E --> F["電腦上完成登入"]
圖9:跨裝置驗證是把手邊的手機當成驗證器使用,並不會把金鑰複製到電腦上。
即使是同步目標不同的電腦,有時也能這樣使用,但這並不能當成存放金鑰的手機遺失時的備援。請把「可以從電腦登入」和「電腦上也註冊了獨立的 Passkey」區分開來。
7. 手機遺失時,要把裝置、認證資訊與工作階段分開處理
遺失時,先從安全的裝置安排遠端鎖定等措施,若懷疑遭到濫用,就儘速聯絡服務或組織的窗口。同時確認能不能用備用的 Passkey 或復原手段進入帳號。不必等到復原完成才去申報遺失或停止使用。裝置的保護、同步帳號的保護與服務端的失效,各自扮演不同的角色。1718
flowchart TB
accTitle: 裝置遺失時要分開確認的事
accDescr: 一邊進行遺失裝置的保護與聯絡窗口,一邊確認安全的復原手段。Passkey 的失效與既有工作階段的終止要分開執行。
A["裝置遺失了"] --> B["遠端鎖定等措施與聯絡窗口"]
A --> C["確認備用金鑰或復原手段"]
B --> D["停止有風險的 Passkey 的使用"]
C --> E["用安全的裝置進入管理畫面"]
D --> F["既有工作階段也另外終止"]
E --> F
F --> G["確認同步目標與已註冊的驗證方式"]
G --> H["在安全的環境準備新金鑰與備援"]
圖10:停用裝置的處理、讓 Passkey 失效的處理,以及終止已登入狀態的處理,是三件不同的事。
如果是固定型,可以在服務端讓遺失驗證器上的認證資訊失效,改用另外註冊的備用認證資訊,這樣的切割是做得到的。在同步型中,多台裝置上的副本從服務端看來是同一份認證資訊,因此一旦在服務端刪除該認證資訊,其他裝置上的副本也就無法再登入同一個服務。要從服務端只讓其中一台裝置的副本單獨失效,未必做得到。102
遠端清除也未必在裝置離線時就會立即生效。在 Apple 的「尋找」中,離線裝置的清除要等到下次連上線時才會開始。19光是把裝置從同步帳號中移除,就判斷該裝置上私密金鑰的副本一定無法再使用,是很危險的。若擔心遭到濫用,就需要判斷是否在各服務端儘速停用、讓對應的認證資訊失效。無法登入時請利用官方窗口,並同時確認讓正當使用者回到帳號的程序。
另外,即使刪除了 Passkey,也未必光憑這樣就能終止所有既有工作階段。請另外確認服務有沒有「從所有裝置登出」之類的功能,同時檢查是否被加入了可疑的 Passkey 或復原目標。2018
在遺失之前,先查清楚重要服務是否支援註冊多把 Passkey,註冊一把獨立的備援並實際試著登入,會比較安心。同步讓同一把金鑰出現在兩台裝置上雖然方便,但這和另外再註冊一把不同的金鑰並不是同一回事。在刪除最後一個登入手段之前,請連同復原碼的保存位置一起,確認自己還有回得去的方法。
8. Passkey 之後仍然存在的弱點在哪裡
Passkey 讓驗證的重要環節變強,但進入帳號的路徑並不只有一般的登入畫面。導入時除了「使用 Passkey 的人是否變多」之外,還要檢查下列這些路徑。
flowchart TB
accTitle: 導入 Passkey 之後仍然存在的攻擊路徑
accDescr: 在 Passkey 登入之外,薄弱的替代手段、復原程序、裝置與保管庫,以及既有工作階段,都仍是攻擊對象。
B["薄弱的替代登入方式"] --> A["對帳號的未授權存取"]
C["濫用復原程序"] --> A
D["裝置與保管庫遭入侵"] --> A
E["濫用工作階段"] --> A
圖11:就算一般的 Passkey 登入很強,其他入口與登入後的狀態仍必須各自防守。
替代登入方式。如果光用密碼或簡訊就能做到同樣的操作,攻擊者就會挑那邊下手。話雖如此,在確認備援與復原手段之前就全面停用,正當使用者也會被擋在門外。要先備妥支援的裝置、備用金鑰與支援程序,再限縮對象、分階段縮減。5
帳號復原與新增金鑰。如果只憑「裝置壞了」的申報就放寬本人確認,就會變成讓攻擊者註冊自己 Passkey 的路徑。重要帳號要把復原申請的確認、新增或刪除驗證方式時的重新驗證、變更通知與稽核組合起來。光是發出通知並不能阻止未經核准的註冊,因此註冊前的確認是必要的。18
裝置與同步保管庫。作業系統與瀏覽器的更新、裝置鎖定,以及掌握保管庫中參與的裝置,仍然是必要的。Passkey 不是一項能把不安全的電腦變成安全電腦的功能。在共用裝置上,也要確認目前的組態允許誰使用這些認證資訊。
工作階段。如果一般的工作階段 Cookie 被竊取而且仍可使用,攻擊者就可能不必重新做 Passkey 驗證也能進行操作。Secure、HttpOnly、適當的 SameSite、有效期間、重新驗證,以及伺服器端的失效等,都要另外設計。HttpOnly 會限制 JavaScript 讀取 Cookie,但無法連 XSS 濫用已登入狀態的操作都擋下來。20
9. 導入自家 Web 服務時的要點
不是呼叫了 API,登入的實作就完成了
WebAuthn 的註冊 API 是 navigator.credentials.create(),驗證 API 是 navigator.credentials.get()。FIDO2 由 WebAuthn 與 CTAP 組成,CTAP 是用戶端與外接安全金鑰等驗證器之間往來的規格。Web 服務的實作者不需要自己寫到 USB 或藍牙的通訊。21
| 名詞 | 主要角色 |
|---|---|
| Passkey | 用來取代密碼的認證資訊 |
| WebAuthn | 從 Web 建立與使用認證資訊的 API,以及其驗證步驟 |
| CTAP | 用戶端與驗證器之間的往來 |
| FIDO2 | 把 WebAuthn 與 CTAP 組合起來的標準架構 |
flowchart TB
accTitle: Web 服務導入 Passkey 的分工
accDescr: 由伺服器負責發出要求與驗證,瀏覽器提供 API,驗證器負責使用金鑰的組態。
S["伺服器:發出要求與驗證回應"] <-->|"要求與回應"| B["瀏覽器:WebAuthn API"]
B <--> O["與作業系統或認證管理員的搭配"]
B <-->|"CTAP 等"| A["外接驗證器"]
圖12:瀏覽器端的呼叫,與伺服器端的驗證及帳號管理要成套實作。
下面是顯示各個值要傳給 API 哪個位置的瀏覽器端骨架。光靠這段片段還不能完成註冊與登入。registrationOptions 與 authenticationOptions 是伺服器為本次嘗試所產生的值,而 challenge、user.id、認證資訊 ID 等二進位項目,也視為已從 JSON 的 Base64URL 字串轉換成適當的位元組序列。2
// 從註冊按鈕的操作呼叫。選項由伺服器發出並保存。
async function createPasskey(registrationOptions) {
if (!window.isSecureContext || !window.PublicKeyCredential) {
throw new Error("這個環境無法使用 Passkey。");
}
const credential = await navigator.credentials.create({
publicKey: registrationOptions,
});
if (!credential) throw new Error("Passkey 的註冊未能完成。");
return credential;
// 由呼叫端把註冊回應序列化後傳送給伺服器。
// 在伺服器驗證成功之前,不要顯示成註冊完成。
}
// 從登入按鈕的操作呼叫,一般的驗證流程。
async function usePasskey(authenticationOptions) {
if (!window.isSecureContext || !window.PublicKeyCredential) {
throw new Error("這個環境無法使用 Passkey。");
}
const assertion = await navigator.credentials.get({
publicKey: authenticationOptions,
});
if (!assertion) throw new Error("Passkey 的驗證未能完成。");
return assertion;
// 由呼叫端把驗證回應序列化後傳送給伺服器。
// 由伺服器驗證,只有成功時才建立工作階段。
}
在實際的畫面上,要在呼叫端處理被拒絕的 Promise,並針對取消、逾時、環境不支援等情況給出說明。註冊回應的二進位轉換與通訊,使用所採用函式庫的對應 API,可以減少實作上的疏漏。
註冊選項中的 authenticatorSelection.residentKey: "required",是用來要求可選擇帳號使用的可探索認證資訊的設定。若設計上要求必須以生物特徵或 PIN 確認,註冊時指定 authenticatorSelection.userVerification: "required",驗證時指定 userVerification: "required"。user.id 要用伺服器發出、最大 64 位元組的不透明識別碼,不要直接使用電子郵件位址,也要與顯示名稱區分開。7
若要使用在登入欄位中以自動填入候選呈現的 Conditional UI,先用 PublicKeyCredential.isConditionalMediationAvailable() 確認支援狀況,再把 mediation: "conditional" 與輸入欄位的 autocomplete="username webauthn" 組合起來。對於不支援的環境,仍要保留上面那種從按鈕出發的一般流程。22
先設計好伺服器要驗證的項目
加密部分的驗證,Node.js 可以用 SimpleWebAuthn,.NET 可以用 fido2-net-lib 等函式庫。不過,有函式庫並不表示與帳號的綁定以及復原設計也會自動變安全。2324
| 要確認的東西 | 實作上要決定的事 |
|---|---|
| 挑戰值 | 以密碼學亂數產生,綁定到本次嘗試與工作階段,並保證期限與只能消耗一次 |
type |
註冊為 webauthn.create、驗證為 webauthn.get,拒絕兩者混用 |
origin |
在伺服器端設定信任的來源,不要拿要求內容自行組出允許清單 |
rpIdHash |
與預期 RP ID 的 SHA-256 比對 |
| 認證資訊與帳號 | 確認 credential ID 與 userHandle 的對應,不要只憑另外輸入的使用者名稱決定登入的帳號 |
| 旗標與簽章等 | 依規格驗證必要的 UP 與 UV、備份狀態的一致性、允許的演算法以及簽章 |
| 註冊回應 | 確認與要求的對應、認證資訊 ID 是否重複,以及必要時的證明(attestation)可信度 |
| 新增、刪除與復原 | 設計既有使用者的重新驗證、CSRF 對策、備用金鑰、變更通知與稽核 |
這張表是實作上的確認觀點,並不能取代規格中的驗證步驟。若要使用 iframe 或關聯來源等,也要把那些額外條件一併確認。在一般的明示驗證中要確認 UP,若把 UV 設為必要,也要確認回應中的 UV。78
flowchart TB
accTitle: 伺服器端的驗證判定
accDescr: 確認與本次要求的對應、使用對象、認證資訊的擁有者,以及簽章與原則全部無誤之後,才發出工作階段。
A["收到驗證回應"] --> B{"是否與本次未使用的要求一致"}
B -->|"是"| C{"使用對象與所屬帳號是否正確"}
C -->|"是"| D{"簽章與必要的驗證結果是否正確"}
D -->|"是"| E["把要求消耗掉一次並發出工作階段"]
B -->|"否"| X["拒絕驗證"]
C -->|"否"| X
D -->|"否"| X
圖13:簽章正確,和這次是否可以讓對方登入該帳號,兩件事都要確認。
signCount 也不是萬能的複製偵測器。有些驗證器不保有計數器而回傳 0,數值未單調遞增的原因也未必就是複製。請確認包含同步型在內的採用環境以及函式庫的處理方式,把異常值用於風險判斷。避免「小於等於上次就一定是複製」「是 0 就安全」這種一刀切的判斷。8
在驗證環境中,要把 WebAuthn 的安全情境要求與 RP ID 的要求分開確認。通常需要 HTTPS,開發用途可以使用 http://localhost。http://127.0.0.1 被視為可信任來源,和能不能把 IP 位址當成 RP ID 是兩回事。WebAuthn 的 RP ID 有網域名稱上的條件,因此開發時也請用 localhost 等所使用瀏覽器能接受的組態來驗證。在那裡建立的認證資訊無法就這樣帶到正式環境的網域使用。925
10. 在 Windows 或公司內部系統要確認什麼
在 Windows 上,重要的是不要光憑「Windows Hello 的畫面跳出來了」這個觀察,就判斷 Passkey 的儲存位置與是否同步。Windows Hello 進行的使用者驗證,和儲存到微軟或其他公司的認證管理員並同步,是要分開確認的項目。既有儲存在本機的 Passkey,也有儲存在同步提供者的 Passkey。26
flowchart TB
accTitle: 在 Windows 導入 Passkey 時的確認順序
accDescr: 依序分開確認登入的對象、認證資訊的儲存位置、組織的允許原則,以及遺失時的復原。
A["要登入什麼"] --> B["區分 Web 服務、Entra ID 與 Windows"]
B --> C["確認 Passkey 的儲存位置與是否同步"]
C --> D["確認驗證方法原則與驗證強度"]
D --> E["驗證備用金鑰與遺失時的程序"]
圖14:同樣是 Windows Hello 的畫面,登入對象與儲存位置不同,維運上的意義也會不同。
保留在 Windows Hello 本機容器中的認證資訊,和同步型的保管庫並不相同。在使用 TPM 的 Windows Hello 組態中,TPM 對金鑰的保護扮演重要角色。不過,不要把 Passkey 的一般分類與有沒有 TPM 混為一談,而要依實際的儲存位置、裝置與組織要求來判斷。2728
在 Microsoft Entra ID 中,要把允許使用 Passkey 的驗證方法原則,和對目標資源要求何種強度驗證的條件式存取驗證強度分開設計。光是讓 Passkey 處於可註冊的狀態,並不會自動把所有存取都限制成抗網路釣魚 MFA。包含同步型在內,允許哪些種類的 Passkey,要依最新的支援狀況與組織原則確認。29
若要讓公司內部 Web 應用程式直接支援 WebAuthn,請先備妥 HTTPS、憑證、名稱解析,以及能當成穩定 RP ID 的網域名稱。若採取把處理交給驗證基礎架構的組態,應用程式端則要設計與該基礎架構的介接與工作階段管理。在 WinForms/WPF 應用程式中使用 Entra ID,和應用程式本身成為 WebAuthn 的 RP,也不是同一件事。
此外,Passkey 並不是一項會自動取代 SMB 共用驗證,或直接修好 NTLM、Kerberos 問題的功能。先決定要改變的是哪一種登入,再從小範圍的對象開始試做註冊、驗證、遺失與復原,才能導入而不中斷業務。
11. 總結 ── 不交出秘密與守好周邊是一整套
Passkey 的強度,在於不把私密金鑰交給登入的對象,而是用與本次要求和使用對象綁定的簽章完成驗證。光是公開金鑰外洩做不出正確的簽章,也無法從無關的假網站使用真網站專用的認證資訊。
另一方面,同步型的保管庫、裝置的鎖定、替代登入方式、復原程序,以及登入後的工作階段,都仍必須持續守護。把換成 Passkey 後可以不用做的對策,和仍然必要的對策分開來看,是正確評估這項導入的觀點。
身為使用者,就去確認儲存位置與復原手段,並為重要帳號準備獨立的備援;身為導入方,就把伺服器端的驗證、多把 Passkey 的管理,以及失效與復原當成一項功能一起設計。做到這個程度,才能把便利性與抗網路釣魚的能力真正帶進實際維運。
相關文章
- Windows 的 TPM 是什麼 ── 圖解「不讓金鑰外流的保險箱」與測量啟動
- 圖解 NTLM 與 Kerberos ── 為什麼驗證會「回退」到 NTLM
- 在 WinForms/WPF 應用程式中導入 Entra ID 驗證 ── MSAL.NET 與 WAM 代理的實務架構
- PowerShell 中安全處理認證資訊 ── 把明文密碼逐出腳本
- Windows 應用程式開發中遵守最低限度安全性的檢核表
- 中小企業的資安對策,該從何開始 ── IPA「中小企業資訊安全對策指南」第4.0版導覽
相關諮詢領域
合同會社小村軟體承接的委外開發,包含公司內部 Web 系統驗證功能的重新檢視、與 Entra ID 的介接,以及把驗證整合進 WinForms/WPF 等 Windows 業務應用程式。在評估是否支援 Passkey 時,我們也不只看登入畫面,而會連同使用的裝置、既有驗證基礎架構與復原程序一起整理。
參考連結
規格與產品資訊確認於 2026 年 9 月 8 日。可使用的功能會因瀏覽器、作業系統與租用戶的設定而異。
-
FIDO Alliance, Passkeys及How Passkeys Work。關於 Passkey 的定位、以公開金鑰加密進行驗證,以及生物特徵資訊的處理方式。 ↩ ↩2 ↩3 ↩4
-
W3C, Web Authentication: An API for accessing Public Key Credentials – Level 3。關於認證資訊、驗證器、API 以及安全性上的前提。 ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
NIST, SP 800-63B-4 — Authenticator and Verifier Requirements。關於密碼、OTP、本機的解鎖資訊,以及抗網路釣魚的能力。 ↩ ↩2 ↩3
-
OWASP, Credential Stuffing Prevention Cheat Sheet。關於利用從其他網站外洩的帳號與密碼組合的攻擊,以及其對策。 ↩
-
CISA, More than a Password。關於針對傳統 MFA 的攻擊,以及往 FIDO/WebAuthn 等抗網路釣魚 MFA 遷移。 ↩ ↩2 ↩3
-
FIDO Alliance Passkey Central, How Passkeys Work。關於註冊、驗證與認證管理員的角色。 ↩ ↩2 ↩3
-
W3C, WebAuthn Level 3 — Registering a New Credential。關於註冊回應、認證資訊 ID、證明(attestation)與綁定到帳號的驗證。 ↩ ↩2 ↩3
-
W3C, WebAuthn Level 3 — Verifying an Authentication Assertion。關於簽章對象,以及挑戰值、來源、RP ID、旗標、帳號對應與簽章計數器的驗證。 ↩ ↩2 ↩3 ↩4
-
W3C, WebAuthn Level 3 — Relying Party Identifier及Related Origin Requests。關於 RP ID 的網域限制,以及關聯來源的明確處理方式。 ↩ ↩2 ↩3
-
FIDO Alliance Passkey Central, Passkey Types。關於同步型與裝置固定型在保管與使用上的差異。 ↩ ↩2
-
Apple, About the security of passkeys。關於 iCloud 鑰匙圈的端對端加密與復原的保護。 ↩ ↩2
-
Google Security Blog, Security of Passkeys in the Google Password Manager。關於私密金鑰同步時的加密與解鎖條件。 ↩
-
Google for Developers, Passkey support on Android and Chrome。關於 Google 密碼管理員的支援環境,以及 Passkey 的使用與復原條件。 ↩
-
NIST, SP 800-63B-4 — Syncable Authenticators。關於可同步驗證器的保護,以及在 AAL2 與 AAL3 的處理方式。 ↩
-
NIST, SP 800-63B-4 — Authentication Assurance Levels。關於 AAL3 對不可匯出私密金鑰與硬體保護等的要求。 ↩
-
FIDO Alliance Passkey Central, Cross-Device Sign-In。關於把手機上的 Passkey 用於另一台裝置登入的機制。 ↩
-
Apple, Use Lost Mode in Find Devices on iCloud.com。關於鎖定遺失裝置與官方的處理程序。 ↩
-
NIST, SP 800-63B-4 — Authenticator Event Management。關於驗證器的新增、遺失與失效、帳號復原以及變更通知。 ↩ ↩2 ↩3
-
Apple, Erase a device in Find Devices on iCloud.com。關於離線裝置的遠端清除會在何時執行。 ↩
-
OWASP, Session Management Cheat Sheet。關於工作階段的保護與失效、Cookie 屬性以及 XSS 對策的範圍。 ↩ ↩2
-
FIDO Alliance Passkey Central, User Authentication Specifications。關於 FIDO2、WebAuthn 與 CTAP 之間的關係。 ↩
-
SimpleWebAuthn, Browser package。關於註冊與驗證的瀏覽器端處理,以及 Conditional UI。 ↩
-
SimpleWebAuthn, Server package。關於註冊與驗證回應的驗證,以及應用程式端要管理的資訊。 ↩
-
fido2-net-lib contributors, fido2-net-lib。關於 .NET 用的 FIDO2/WebAuthn 函式庫與導入範例。 ↩
-
W3C, Secure Contexts — Is origin potentially trustworthy?。關於包含 localhost 與回送位址在內的安全情境判定。 ↩
-
Microsoft Support, Manage your saved passkeys。關於 Windows 上的本機儲存與同步提供者的管理。 ↩
-
Microsoft Learn, Support for passkeys in Windows。關於 Windows 的 Passkey 支援,以及 Windows Hello 與 TPM 的關係。 ↩
-
Microsoft Learn, Enable Microsoft Entra passkey on Windows。關於儲存在 Windows Hello 本機容器中的 Entra Passkey。 ↩
-
Microsoft Learn, Enable passkeys (FIDO2) in Microsoft Entra ID及Passkeys (FIDO2) authentication method。關於 Passkey 的種類、驗證方法原則與驗證強度的設定。 ↩
相關文章
共用相同標籤的最新文章。能以相近的主題延伸理解。
Windows 憑證存放區實務指南 ── 該放進使用者,還是電腦?
用戶端憑證應該放進使用者存放區還是電腦存放區?從 certmgr.msc 與 certlm.msc 的差異、私密金鑰的權限授予,到用 PowerShell 進行到期日盤點,本文有系統地整理憑證常見事故的解法。
WSUS 淘汰後的 Windows Update 管理 ── 該如何選擇 WUfB、Autopatch、Intune
2024 年 9 月,Microsoft 宣布 WSUS 淘汰。雖然不會馬上停止運作,但新功能開發已經終止。本文將 WSUS 續用、Windows Update for Business、Autopatch、Intune 這四個選項,整理成一份包含授權與閉域網路條件的判斷表。
BitLocker 實務指南 ── 回復金鑰的尋找方式與安全管理
BitLocker 的回復金鑰到底在哪裡。說明在回復畫面上的尋找方式、加密百分比與保護狀態的差別、Windows 11 的自動加密、公司電腦的金鑰管理,以及 BIOS 更新、送修、廢棄時的注意事項。
圖解NTLM與Kerberos ── 為什麼驗證會「回退」到NTLM
以圖解方式整理NTLM與Kerberos的差異。內容涵蓋挑戰/回應、TGT與服務票證、無法解析SPN時Negotiate回退到NTLM的條件、中繼攻擊與Pass-the-Hash成立的原因,以及NTLMv1遭到移除的來龍去脈,並附上官方文件佐證。
Windows 的 TPM 是什麼 ── 圖解「不讓金鑰外流的保險箱」與測量啟動
本文以圖解說明 TPM。從不讓金鑰離開晶片的機制、PCR 與測量啟動、在 BitLocker 與 Windows Hello 中的使用方式、dTPM/fTPM/Pluton 的差異、用 Get-Tpm 確認的方法,到被要求輸入回復金鑰時該怎麼處理,全部以實務角度整理。
相關主題
與本文相近的主題頁面。以本文為起點,可進一步連到相關服務與其他文章。
Windows 技術主題
彙整 KomuraSoft LLC 關於 Windows 開發、故障調查與既有資產活用文章的主題中心。
常見問題
整理諮詢這個主題時常見的問題。
- Passkey 為什麼比密碼安全?
- 因為它不把私密金鑰交給登入的對象,而是用與本次挑戰值和使用對象綁定的簽章完成驗證。只外洩公開金鑰無法偽造簽章,也無法從無關的假網站使用真網站專用的 Passkey。不過,伺服器端的正確驗證,以及裝置、復原手段與工作階段的保護仍然必要。
- 指紋或臉部資訊會被傳送到網站嗎?
- WebAuthn 的驗證回應不會夾帶指紋影像或臉部特徵值傳送給登入的對象。生物特徵驗證與 PIN 是在使用者端用來許可私密金鑰的使用,服務端確認的則是簽章與使用者驗證的結果。
- 既然不傳送私密金鑰,為什麼 Passkey 還能同步?
- 因為對登入對象的驗證,和認證管理員的同步是兩條不同的路徑。同步型會把私密金鑰加密後複製到各裝置之間,但並不是把私密金鑰交給登入的對象。同步保管庫的解鎖與復原條件會因產品與設定而異。
- 手機遺失後,使用 Passkey 的帳號會怎麼樣?
- 同步型在滿足保管庫的復原條件時,有機會在另一台裝置上繼續使用;裝置固定型則需要另外註冊的備用認證資訊或復原手段。在保護裝置與申報遺失的同時,確認安全的復原手段,並把有風險的認證資訊失效與既有工作階段的終止分開執行。如果在服務端讓同一份已同步的認證資訊失效,其他裝置上的副本也將無法再登入該服務。
- 用了 Passkey 就不需要網路釣魚對策了嗎?
- 並非如此。Passkey 在防止把認證資訊交給假網域這件事上很強,但誘導改用密碼或簡訊、濫用復原程序、裝置或工作階段遭入侵,都需要另外採取對策。
- 在 Windows Hello 中使用的 Passkey 一定是裝置固定型嗎?
- 光看 Windows Hello 的確認畫面,無法判斷儲存位置與是否同步。要把本機容器中的認證資訊,和儲存在同步提供者中的 Passkey 區分開來,並確認實際的儲存位置、裝置與組織原則。