別因不安全的密碼讓你的資料裸奔了,了解一下如何為網站加上 WebAuthn 無密碼驗證吧

前言

你有沒有曾經使用 Google 瀏覽器登入某個網站時,突然跳出「你的密碼已遭洩露」的訊息? 除非你用的密碼堅不可摧、每個網站都設定不同,否則你多多少少應該都會遇到這種情況吧。


如果你的回答是 No,我的密碼很安全,怎麼可能發生在我身上的話,你也別高興得太早,國外有位工程師寫了一個網站叫做 Have I been pwned ,收集了過去數年來洩露的數十億筆密碼資料 (我強烈懷疑這工程師自己也是暗網的潛在賣家,不然誰身上可以蒐集到這麼多資料呢 XD),只要你輸入常用的帳號,這網站就會告訴你是否有洩漏的風險,如下圖,我自己電子郵件信箱也無法倖免。


好啦,言歸正傳。近年來,資安意識興起,各大網站都開始提倡 MFA (多重要素驗證),就連我國內政部的系統也開始全面無密碼化,改用自然人憑證來進行登入,但對於個人開發的小網站,要求使用者安裝額外設備或 APP 來實現多因素認證,未免太不切實際。

如果有一種機制,可以直接利用大家都有的手機來進行驗證,是不是就更完美了呢?WebAuthn 就是為了這個目的所存在的。


起因

為什麼會寫這個主題呢?其實是因為上學期我在成大碩專班的資安課程,有個 Zero Trust Architecture 的期末報告,老師提到如果有實作會有額外的加分,於是我們小組便決定,既然要做,不如就做一個簡單的系統,讓大家可以更清楚的了解這個架構是怎麼運作的,底下是實作完成的影片,影片中有一段黑畫面沒辦法錄到,但那段是我們呼叫手機的指紋驗證器進行登入驗證的過程。


在開始運作原理之前,先看一下我們的題目,NIST SP 800-207 第三章:零信任架構邏輯元件,EIG Crawl Phase 的參考架構圖。



WebAuthn 是什麼 ?

WebAuthn,全名 Web Authentication,是一種基於非對稱加密技術的身份驗證方式,主要是希望取代傳統的密碼驗證,並用於網站的註冊、登入以及雙因素認證(2FA)等場景。這個技術不僅能夠有效解決釣魚攻擊和數據泄露等安全問題,同時還能提升用戶的使用體驗,因為使用者不必再記憶複雜的密碼。

通過 WebAuthn 提供的 API,我們可以輕鬆實現指紋識別、人臉識別等生物特徵的驗證,或者是利用加密硬體,如USB Key、藍牙設備等進行身份驗證。

簡單來說,WebAuthn 讓使用者可以直接使用自己已有的設備來進行身份驗證,從而實現更加安全、方便的登入流程。


FIDO2

FIDO2 規範包含了 WebAuthn 與 Client-to-Authenticator Protocol (CTAP),先說明底下幾個專有名詞

  • FIDO,Fast IDentity Online : 是一個組織,也是一系列協議標準。
  • WebAuthn,Web Authentication : 非對稱加密的方式,瀏覽器內建 2FA API。
  • CTAP : 客戶端到認證器協議。
  • RP, Relying Party : 依賴認證服務方,比如網站系統的服務器。
  • Authenticator : 用來替代密碼進行認證的設備,如指紋傳感器。

圖片資料來源 : https://blog.techbridge.cc/2019/08/17/webauthn-intro

上圖為 FIDO2 的運作流程,主要可以分成註冊及驗證兩大流程,兩者的流程也大同小異,僅差異在驗證流走或需要簽章(簽名)的部分。

  • 使用者透過瀏覽器要求伺服器(你的機器)提供註冊/驗證的參數,此步驟不見得一定要後端產生,但後端產生可以記住 challenge Id 並進行後續的驗證,已避免 Relay attack。
  • 取得註冊/驗證參數後,將此參數透過瀏覽器 API 送出請求,此時瀏覽器會跳出註冊方式,你可以選擇實體裝置(手機)或 USB Key。
  • 註冊流程 Only,以實體裝置為例,在收到來自瀏覽器的請求並通過驗證(可能是指紋、或 PIN 碼),會在裝置留下 Private Key,並將 Public Key 回傳給瀏覽器,瀏覽器收到後,將 Public Key 送到伺服器端保存。
  • 驗證流程 Only,以實體裝置為例,在收到來自瀏覽器的請求並通過驗證(可能是指紋、或 PIN 碼),會使用 Private Key 進行簽名,並將結果回傳給瀏覽器,瀏覽器收到後,將此簽章提供給伺服器進行驗證。


JWT Token

JSON Web Token,簡稱 JWT,主要是為了符合 RESTful API 在 HTTP 請求無狀態而誕生的,也就是每一次從客戶端向伺服器端發出的請求都是獨立的,其主要的結構可分成,Header、Payload、Signature 三大部分,前兩個部分使用 base64 編碼後再進行字串相加組合而成,因此算是明碼的傳輸,因此重要資訊不可放置於此處。

圖片左邊處就是 JWT Token 的內容,右方上方 Header 的部分描述 JWT 的加密演算法,中間 Payload 的部分描述簽發的權限的相關資訊、包含效期、角色等等資訊,請注意這邊不應該包含敏感資料,底下則為簽名的部分。

請注意因為 JWT 一但簽發本身並不具備 Revoke 的機制,因此必須在授權中心實作黑名單的機制,一但重要資訊外洩,必須將所以已簽發並且尚未失效的 Token 全部標記失效。


實做架構

我們的實作方式與市場上商用設備或軟體的 ZTA 架構有所不同,我們的目標是在不購買額外設備的前提下,針對傳統 Web 應用程式進行 ZTA 結構的補強,因此我們專注於強化登入階段的雙因素驗證和核發權限後的覆核及監控等授權流程,底下為幾個重要元件的職責說明。

  • PDP  : 自行開發授權中心擔任 PA 的角色,並由 Redis 來充當 PE,兩者合併成構成政策決策點。
  • 雙因素驗證機制 (非對稱加密) : 使用 FIDO2 協議來實做此部分,FIDO 會在下一個章節說明。
  • 權限核發 (對稱加密) : 使用 JWT Token 機制來實作,核發一個短效期的 Token。
  • 權限 Review : 在有效期限內,重新檢視權限並派發新的權限的 Token。
  • 檢核黑名單並同步 Token (未實作) : 這部分規劃,定期同步被鎖定或被監控異常的相關資訊到 Redis。
實作架構

而授權的流程,則是如上圖。

  1. 使用者透過瀏覽器進行登入。
  2. 此時會使用 Web Authentication 的運作機制來跟授權中心要求驗證。
  3. 授權中心會透過 Redis 的政策設定來決定是否該提供本次的存取,這個部分的資訊是定期同步的。
  4. 若通過授權,授權中心則會簽發一個有期限的 JWT Token 給予登入端的應用程式,並且授權中心會記下該憑證及效期。
  5. 應用程式則可使用此 Token 來跟各微服務來取得相對應的資源。
  6. PE 會定期同步來自於 PIP 的各項資訊,來決定是否將該 Token 的授權是否存續、展延或者拒絕存取。

各流程實作示意圖

底下是註冊及登入的操作介面,這邊我並沒有實際把雙因素驗證綁在登入後驗證,在實務上若要做到更嚴謹,需要在使用者登入後,再進行第二因子的驗證,若有興趣的人也可以自己實做看看。

雙因素註冊

使用者可透過 Windows Hello、與當前瀏覽器登入相同帳號的行動裝置、或行動裝置掃描 QRCode 的方式來進行裝置的註冊。 PS. Windows Hello 必須支援 TPM 模組的筆電才能測試,這點我就沒有測試到了。


無密碼登入

再有輸入帳號的情況下,若事先有註冊雙因素驗證,則預設會跳出先前註冊的裝置資訊。


裝置驗證

若完全不輸入帳號,則由使用者自行決定要使用哪個裝置來進行驗證,右圖則為驗證器收到後須自行選擇要使用的憑證。


WebAuthn 公私鑰

Private 儲存在手機端,若使用者不使用時可自行在自己的裝置移除。



參考網站

【臺灣資安大會直擊】零信任架構該如何對應企業實務的資安防護規畫?思科提出3W評估模式

【ZTA 101】NIST SP 800-207第三章:零信任架構邏輯元件

不買新產品,你要怎麼做到零信任架構?

零信任(二)NIST 架构与思考总结

NIST SPECIAL PUBLICATION 1800-35B

WebAuthn 實做範例

Web 應用身份驗證的未來?WebAuth 介紹

留言