本文件說明 userVerification
在 WebAuthn 中的情況,以及當在建立或驗證密碼金鑰時指定 userVerification
時,瀏覽器的行為。
WebAuthn 中的「使用者驗證」是什麼?
密碼金鑰的建構基礎採用公開金鑰密碼編譯技術。建立密碼金鑰後,系統會產生公開/私密金鑰組,供密碼金鑰提供者儲存私密金鑰,然後將公開金鑰傳回給依賴方 (RP) 伺服器來儲存。伺服器可以使用配對的公開金鑰,驗證由相同密碼金鑰簽署的簽名,藉此驗證使用者。公開金鑰憑證上的「使用者存在」(UP) 標記可證明在驗證期間,曾與裝置互動。
使用者驗證是選用的安全防護層,會在驗證期間聲明存在正確的人員,而非只有某些人,也就是使用者俱備的聲明。在智慧型手機上,通常是使用螢幕鎖定機制 (無論是生物特徵辨識,還是 PIN 碼或密碼)。系統是否會在驗證密碼金鑰時,將「UV」旗標記錄於驗證器資料中 (該旗標會在註冊和驗證密碼金鑰時傳回)
![macOS iCloud 鑰匙圈使用者驗證對話方塊的螢幕截圖。對話方塊會提示使用者透過 Touch ID 登入,並顯示要求驗證的來源和使用者名稱。對話方塊右上方有標示為「取消」的按鈕。](https://web.dev/static/articles/webauthn-user-verification/image/fig-1.png?authuser=7&hl=zh-tw)
![Android 版 Chrome 使用者驗證對話方塊的螢幕截圖。對話方塊會提示使用者使用臉部辨識或指紋偵測功能驗證身分,並顯示要求驗證的來源。畫面左下方會顯示使用 PIN 碼進行驗證的選項。](https://web.dev/static/articles/webauthn-user-verification/image/fig-2.png?authuser=7&hl=zh-tw)
伺服器上的 UP 和 UV 驗證方式
使用者狀態 (UP) 和使用者已驗證的 (UV) 布林值標記,會在驗證器資料欄位中向伺服器傳送信號。在驗證程序中,您可以利用儲存的公開金鑰驗證簽名,驗證驗證器資料欄位的內容。只要簽章有效,伺服器就能將標記視為正版。
![驗證資料結構的說明。從左到右,資料結構的每個部分依序讀取了「RP ID HASH」(32 位元組)、「FLAGS」(1 位元組)、「COUNTER」(4 個位元組、big-endian uint32)、「ATTESTE CRED」。DATA (如有可變長度) 和「EXTENSIONS」(如果有的話,可變長度 (CBOR)。)展開「FLAGS」區段,顯示由左至右標示的潛在標幟清單,標籤為「ED」、「AT」、「0」、「BS」、「BE」、「UV」、「0」和「UP」。](https://web.dev/static/articles/webauthn-user-verification/image/fig-3.png?authuser=7&hl=zh-tw)
註冊密碼金鑰和進行驗證時,伺服器應檢查 UP 旗標是否為 true
,以及 UV 旗標是 true
還是 false
(取決於需求)。
指定 userVerification
參數
根據 WebAuthn 規格,RP 可以使用 userVerification
參數,在建立憑證及斷言時要求使用者驗證。它分別接受 'preferred'
、'required'
或 'discouraged'
,這表示:
'preferred'
(預設):建議在裝置上使用使用者驗證方法,但如果沒有這個驗證方法,可以略過。如果執行使用者驗證,回應憑證會包含true
的 UV 旗標值;如未執行 UV,則為false
。'required'
:必須叫用裝置上可用的使用者驗證方法。如果沒有可用,則要求在本機會失敗。這表示回應憑證一律會傳回 UV 旗標設為true
。'discouraged'
:不建議採用使用者驗證方法。不過,視裝置而定,系統仍可能會執行使用者驗證,且 UV 旗標可能包含true
或false
。
建立密碼金鑰的程式碼範例:
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'
。
在許多環境中,使用者驗證流程會比保護措施更安全。舉例來說,如果 macOS 無法使用 Touch ID (因為裝置不支援、已停用或處於貝殼式模式),系統會要求使用者改為輸入系統密碼。這會造成不便,且使用者可能會完全放棄驗證程序。如果排除重新導向比較重要,請使用 userVerification='preferred'
。
![在無法使用 Touch ID 時,macOS 顯示的密碼金鑰對話方塊螢幕截圖。對話方塊包含要求驗證的來源及使用者名稱等資訊。對話方塊右上方有標示為「取消」的按鈕。](https://web.dev/static/articles/webauthn-user-verification/image/fig-4.png?authuser=7&hl=zh-tw)
使用 userVerification='preferred'
時,如果成功執行使用者驗證,UV 旗標為 true
;如果略過使用者驗證,則為 false
。舉例來說,在無法使用 Touch ID 的 macOS 上,系統會要求使用者點選按鈕來略過使用者驗證程序,而公開金鑰憑證則包含 false
UV 旗標。
UV 旗標會在風險分析中列為信號。如果因其他因素導致登入嘗試有風險,建議您在未執行使用者驗證時向使用者提出額外的登入驗證問題。
使用「userVerification='required'
」的時機
如果認為 UP 和 UV 都絕對必要,請使用 userVerification='required'
。
這個選項的缺點是,使用者登入時可能會遭遇更複雜的問題。舉例來說,如果 macOS 無法使用 Touch ID,系統會要求使用者輸入系統密碼。
透過 userVerification='required'
,您可以確保在裝置上進行使用者驗證。確認伺服器會驗證 UV 旗標為 true
。
結論
透過使用者驗證機制,由密碼金鑰負責的各方可以評估裝置擁有者登入的可能性。您可自行決定是否要求使用者驗證,或視備用登入機制對使用者流程的重要程度而定。確認伺服器會檢查 UP 旗標和 UV 旗標,以便進行密碼金鑰使用者驗證。