使用者驗證深入解析

本文件說明 WebAuthn 中的 userVerification,以及在建立密碼金鑰或驗證期間指定 userVerification 時產生的瀏覽器行為。

何謂「使用者驗證」該怎麼辦?

密碼金鑰採用公開金鑰密碼編譯技術。建立密碼金鑰後,系統會產生公開/私密金鑰組,密碼金鑰供應商會儲存私密金鑰,然後將公開金鑰傳回依賴方 (RP) 伺服器加以儲存。伺服器可以使用配對的公開金鑰,驗證由同一個密碼金鑰簽署的簽章,藉此驗證使用者。「使用者存在」公開金鑰憑證上的 (UP) 標記可證明有人在驗證期間與裝置互動。

使用者驗證是選擇性的一層安全性防護,其目的是要在驗證期間斷言驗證的對像是正確的人員,而非只有個人,做為使用者的聲明。在智慧型手機上,螢幕鎖定機制通常是透過生物特徵辨識技術、PIN 碼或密碼來完成。使用者是否驗證作業是否在「紫外線」中回報密碼金鑰註冊和驗證期間,驗證器資料中傳回的旗標

macOS 上 iCloud 鑰匙圈的使用者驗證對話方塊螢幕截圖。對話方塊會提示使用者使用 Touch ID 登入,其中顯示要求驗證的來源以及使用者名稱。對話方塊右上方會顯示標示為「取消」的按鈕。
macOS 上的 iCloud 鑰匙圈使用者驗證對話方塊。
,瞭解如何調查及移除這項存取權。
Google Chrome Android 版使用者驗證對話方塊的螢幕截圖。對話方塊會提示使用者使用臉部辨識或指紋偵測功能來驗證身分,並顯示要求驗證的來源。你可以在左下方使用 PIN 碼進行驗證。
Android Chrome 上的使用者驗證對話方塊。

如何在伺服器上驗證 UP 和 UV

系統會在驗證器資料欄位中,向伺服器傳送使用者目前狀態 (UP) 和使用者已驗證 (UV) 布林標記。在驗證期間,您可以使用儲存的公開金鑰來驗證簽章,藉此驗證驗證器資料欄位的內容。只要簽章有效,伺服器就能真正將旗標視為真實存在的標記。

驗證資料結構的描述。從左到右,資料結構的各部分都顯示「RP ID HASH」(32 個位元組)、「FLAGS」(1 個位元組)、「COUNTER」(4 個位元組,big-endian uint32)、「ATTESTE CRED.DATA(可變長度) 和「EXTENSIONS」(CBOR) 可變長度 (CBOR)。《FLAGS》展開的區段,以從左到右顯示可能的標記清單:「ED」、「AT」、「0」、「BS」、「BE」、「UV」、「0」和「UP」。
公開金鑰憑證中的 Authenticator 資料欄位。

在密碼金鑰註冊和驗證過程中,伺服器應檢查 UP 標記為 true,以及 UV 標記是 true 還是 false (取決於需求條件)。

指定 userVerification 參數

根據 WebAuthn 規格,RP 可以在憑證建立和斷言都使用 userVerification 參數,要求使用者進行驗證。它接受 'preferred''required''discouraged',分別代表:

  • 'preferred' (預設):建議在裝置上採用使用者驗證方法,如果無法使用,可以略過這個步驟。如果執行使用者驗證,回應憑證會包含 true 的 UV 標記值;如果執行 UV,則為 false
  • 'required':必須在裝置上叫用可用的使用者驗證方法。如果沒有可用方法,要求會在本機執行。這表示回應憑證一律會傳回,同時 UV 標記設為 true
  • 'discouraged':不建議採用使用者驗證方法。不過,視裝置而定,系統還是可以執行使用者驗證,且 UV 標記可能包含 truefalse

建立密碼金鑰的程式碼範例:

const publicKeyCredentialCreationOptions = {
  // ...
  authenticatorSelection: {
    authenticatorAttachment: 'platform',
    residentKey: 'required',
    requireResidentKey: true,
    userVerification: 'preferred'
  }
};

const credential = await navigator.credentials.create({
  publicKey: publicKeyCredentialCreationOptions
});

密碼金鑰驗證程式碼範例:

const publicKeyCredentialRequestOptions = {
  challenge: /* Omitted challenge data... */,
  rpId: 'example.com',
  userVerification: 'preferred'
};

const credential = await navigator.credentials.get({
  publicKey: publicKeyCredentialRequestOptions
});

您該為userVerification選擇哪一個選項?

要使用的 userVerification 值取決於應用程式要求,以及使用者體驗需求。

使用「userVerification='preferred'」的時機

如果您將使用者體驗勝過保護功能,請使用 userVerification='preferred'

在某些情況下,使用者驗證作業會比保護設定更流暢。舉例來說,在無法使用 Touch ID 的 macOS 上 (由於裝置不支援、已停用或裝置處於貝殼式模式),系統會要求使用者改為輸入系統密碼。這會造成問題,使用者也可能完全放棄驗證。如果您更重視排除阻礙,請使用 userVerification='preferred'

macOS 無法使用 Touch ID 時顯示的密碼金鑰對話方塊螢幕截圖。對話方塊中含有要求驗證的來源和使用者名稱等資訊。對話方塊右上方會顯示標示為「取消」的按鈕。
macOS 無法使用 Touch ID 時顯示密碼金鑰對話方塊。

使用 userVerification='preferred' 時,如果成功執行使用者驗證,UV 旗標為 true;如果略過使用者驗證,則為 false。舉例來說,在無法使用 Touch ID 的 macOS 中,系統會要求使用者點選按鈕來略過使用者驗證,而公開金鑰憑證中會包含 false UV 標記。

UV 旗標可做為風險分析中的信號。如果登入嘗試由於其他因素導致登入風險,建議在使用者未驗證的情況下,要求使用者進行其他登入驗證。

使用「userVerification='required'」的時機

如果你認為 UP 和 UV 皆為絕對必要,請使用 userVerification='required'

不過,這個選項的缺點是使用者可能會遇到登入問題。舉例來說,在無法使用 Touch ID 的 macOS 上,系統會要求使用者輸入系統密碼。

使用 userVerification='required' 可確保使用者驗證在裝置上執行。確認伺服器驗證 UV 標記是否為 true

結論

密碼金鑰依賴方採用使用者驗證機制,有助於評估裝置擁有者登入的可能性。使用者可自行決定是否需要使用者進行驗證,也可以依備用登入機制對使用者流程的影響程度,選擇是否要求使用者驗證。確認伺服器會檢查 UP 標記和 UV 標記,以取得密碼金鑰使用者驗證。