無密碼登入時代 - WebAuthn 與 Passkey
2 |
密碼仍是當代最常用的身分識別方式,但密碼也是使用者跟系統管理的痛苦來源之一。密碼太短太簡單容易被猜中,太長太複雜記不住,忘記了要重設自己煩客服也煩;對系統管理者,密碼如燙手山芋,儲存得加鹽並慎選雜湊演算法才安全(延伸閱讀:密碼要怎麼儲存才安全?該加多少鹽?-科普角度)(當然隨便雜湊加密湊數,甚至直接存明碼的也大有人在)。儲存密碼主機在駭客眼中是塞滿金條的保險箱,屬兵家必爭之地,得時時提防,一刻不能放鬆。
FIDO 聯盟 2019 有份投影片統計密碼產生多少成本:全球所有人每天花在敲密碼的時間加起來有 1300 年、81% 資料洩漏跟不安全密碼有關、大公司花在密碼重設的成本一年要一百萬美金、20~50% 的 IT 客服電話跟重設密碼有關(每通成本 70 USD)、49% 購物車因為密碼問題最後沒結帳...
這幾年在 FIDO 聯盟推動下,催生了無密碼登入的新規格 - FIDO2 專案,結合手機指紋/臉孔識別、實體金鑰等高度安全的認證器(Authenticator)硬體,以密碼學公私鑰取代文字密碼做為身分驗證依憑。公私鑰機制遠比文字密碼安全的原因有二,第一是金鑰相當於 256 位以上的文數字加符號密碼(以 RSA2048 為例),以目前的電腦算力跑上一萬年也無法暴力破解,第二是解密關鍵的私鑰自始至終都鎖在晶片裡面(註:啟用跨裝置雲端共享金鑰會喪失此優勢),無法被讀取也不會在網路上傳輸,不存在密碼外流風險。(使用者的關鍵秘密永遠封在自己的硬體裝置裡,系統管理者不再負保管之責,終於可以鬆一口氣了)
FIDO2 包含兩個標準 - WebAuthn 標準與 CTAP2 (Client To Applicator Protocol 2) 協定,用白話解釋是一套讓瀏覽器、認證器與伺服器三者溝通,不靠密碼而是用數位簽章完成身分認證的通信協定。FIDO UAF 實現在終端裝置使用指紋、聲音辨識、PIN 碼無密碼登入,FIDO2 則將範圍擴大到更多平台與裝置。
要深入 FIDO2,有幾個術語要了解:
- Authenticator - 驗證器,指可以產生公鑰和私鑰的裝置,在使用者證明自己身分後以私鑰簽署 Assertion。常見的驗證器包含筆電或行動裝置內建的指紋掃描器及臉孔識別、實體金鑰、智慧晶片卡等。
題外話:Windows Hello 指紋掃瞄與臉孔識別是透過 SDCP/TLS 安全協定與主機溝通,而私鑰保存於主機的硬體安全模組,因此有可能被繞過,但破解需拆硬體,稍有難度。參考 相較之下,實體金鑰或智慧晶片卡的私鑰儲存在自身內部,無被繞過疑慮。 - WebAuthn - Web Authentication API,由 W3C 發佈的標準,瀏覽器需支援 WebAuthn 才能實現無密碼登入,目前主流瀏覽器幾乎都已加入支援。
- Relying Party - 需要使用者驗證身分的服務或應用程式。登入時 Relying Party 發出挑戰,Authenticator 會回應這個挑戰(數位簽名),然後 Relying Party 驗證回應判定使用者是否為本人。
- CTAP - 客戶端到身分驗證器協定,目前有兩個版本 CATP1(即原本的 FIDO U2F) 及 CTAP2,驗證器依支援版本不同,習慣稱為 U2F 驗證器及 FIDO2 驗證器,前者主要支援雙因子驗證,後者能整合瀏覽器支援無密碼驗證。
- Client Device - 客戶端裝置,即使用者在使用的電腦、平板、手機等實體設備。
- User-Verifying Platform Authenticator - 可識別使用者身分的平台裝置內建的驗證器,常見的有 TouchID/Face ID (macOS 及 iOS)、Windows Hello、Android Device Unlock (指紋、臉孔、PIN)。而實體金鑰、智慧晶片卡則屬於 Roaming Authenticator。
- 註冊(Registration) - 在這個階段,驗證器會生成一個新的公私鑰對,私鑰保存在驗證器內部,不需要也無法被傳輸,公鑰則使用會用驗證器自身的 Attestation 憑證(製造時寫入,同一機型憑證相同)簽名後傳送給 Relying Party,這個過程稱為 Attestation,其格式依驗證器型式不同(如:Packed、TPM、Androd Key Attestation、FIDO U2F...)。參考
藉由驗證器提供憑證或簽章證明,可幫助 Relying Party 了解驗證器的製造商、模型、安全等級等,確保其有效性及可信賴度。 - 登入(Authentication/Login) - 當使用者嘗試登入 Relying Party,Relying Party 會發送一個挑戰給客戶端裝置,客戶端裝置將這個挑戰傳送給驗證器。之後,Authenticator 要求用戶進行身份驗證(例如輸入 PIN 碼或進行生物識別),若身份驗證成功,Authenticator 會用其私鑰簽署挑戰,產生一個稱為 Assertion 的簽名回應。客戶端裝置將 Assertion 傳送回 Relying Party。最後,Relying Party 用先前在註冊階段得到的公鑰來驗證 Assertion。若驗證成功,則視為使用者已成功登入。
- Passkey 是一種數位認證信物(Credential),可取代密碼用於向網站或應用程式驗證身分,通常由作業系統或瀏覽器儲存,並可通過雲端在不同裝置間,或者也可以只存在於單一的實體金鑰等物理裝置中,參考 而 WebAuthn 即為幫助網站與瀏覽器實作 Passkey 身分認證的一套規格。
關於 WebAuthn 機制的註冊與登入流程,這裡借用 FIDO 聯盟的圖與說明。
註冊
- 使用者連上網站的註冊頁面
- 使用指紋、PIN 碼解鎖驗證器(手機、實體金鑰)
- 驗證器為該網站產生一把新的公私鑰對(原本有 A、B,再產生一把該網站專屬 C)
- 公鑰傳給網站保存,網站將公鑰與使用者帳號建立關聯
- 私鑰則永遠存在驗證器內,無法取出 (不存在被入侵偷走或釣魚網站騙走的風險)
登入
- 網站送出 Challenge 給使用者設備
- 使用指紋、PIN 碼解鎖驗證器(手機、實體金鑰)
- 依據網站 URL 在驗證器找到該網站專屬私鑰 C,對 Challenge 做數位簽名
- 將簽名後的 Challenge 傳回網站,網站找出該帳號對應公鑰驗證簽名是否為真,若真則允許使用者登入
Google、Github、PayPal、Microsoft O365/XBOX、Amazon... 等網站都已支援 Passkey 登入,但我有興趣的部分是自己寫個網站支援 Passkey 登入,WebAuthn.io 有個 Passkey 登入測試網站是不錯的實驗對象。我錄了一段影片,展示用 Android 手機指紋解鎖產生金鑰完成註冊,之後再使用金鑰完成登入:
這個登入測試未來可做為自己開發網站的對照,流程並不複雜,預期應能順利搞定。
最後補充:WebAuthn.io 為測試用途,只會保存你的公鑰 24 小時,之後手機上的金鑰就作廢了。要如何刪除存在手機的 Passkey?操作方法如下:
【延伸閱讀】
Simple introdcution to FIDO2, WebAuthn and Passkey.
Comments
# by Sophie
Debug: CTAP2 (Client To Application Protocol 2) 協定: 應是 Client to "Authenticator" Protocol
# by Jeffrey
to Sophie, 感謝,已修正。