FIDO U2F應用與開發(一)-原理與協議
??FIDO(Fast IDentity Online聯盟)是一個基於標準、可互操作的身份認證生態系統。
??U2F(Universal 2nd Factor)是FIDO聯盟提出的使用標準公鑰密碼學技術提供更強有力的身份認證協議。
??U2F在常用的用戶名/密碼的認證基礎上又增加了一層第二因子(2nd Factor)的保護,這重保護是通過物理硬件來支持的。
2. U2F協議原理
??FIDO的官方網站用兩張圖介紹了U2F的應用原理,它把應用過程分解為兩個階段:
??註冊階段,如圖1所示:
??圖1中的流程如下:
- 客戶端提示用戶選擇符合在線服務策略的可用 的U2F設備。
- 用戶使用U2F設備上的按鈕解鎖 U2F設備。
- U2F設備創建一對針對本地設備、在線服務和用戶賬戶的獨有的全新公/私鑰對。
- 客戶端將公鑰發送給在線服務,並將其與用戶的賬戶關聯,私鑰存放在U2F設備中。
??鑒權階段,如圖2所示:
??圖2中的流程如下:- 在線服務要求用戶使用之前註冊使用的U2F設備登錄。
- 用戶使用U2F設備上的按鈕解鎖 U2F設備。
- 設備使用由服務器提供的用戶的賬戶標識來選擇正確的密鑰並簽名服務器發出的挑戰值。
- U2F設備將經過簽名的挑戰發送回服務器,由其使用存儲的公鑰進行驗證,服務器驗證成功後允許用戶登錄。
??U2F的原理很簡單:用戶需要使用用戶名/口令、客戶端設備(物理設備)兩重安全因子完成在線服務網站的註冊與登錄鑒權工作;用戶在向在線服務註冊期間,用戶的客戶端設備會創建一個新的密鑰對。該設備保留私鑰,並向在線服務註冊公鑰;用戶在登錄鑒權期間,客戶端通過對挑戰值簽名的方式向該服務證明私鑰的擁有權,以此完成身份認證。其實這與我們日常使用的網上銀行登錄時需要插入USB Key沒有什麽區別,可能唯一的技術差別在於瀏覽器在識別銀行的USB Key使用的是特定的插件,而對於U2F設備,瀏覽器已經內置了識別接口。3. U2F協議的消息格式
??U2F協議支持兩個操作:註冊(registration)與鑒權(authentication),這兩個操作可分解為三個階段,如圖3所示。
??在圖3中,Relying Party(簡稱RP)就是第2節描述的在線服務網站。FIDO Client為客戶端,三個階段的流程如下:- Setup:在這個階段,客戶端向在線服務網站請求一個挑戰值,客戶端使用這個挑戰值生成一個請求消息發送到U2F設備。
- Processing:在這個階段,U2F設備針對請求消息做一些密碼學的操作,並創建回應消息。
- Verification:在這個階段,客戶端將U2F設備的回應消息交給服務端進行驗證,服務端處理回應消息並驗證其正確性。對於一個正確的註冊回應使得服務端為用戶註冊一個公鑰;對於一個正確的鑒權回應使得服務端相信用戶擁有一個正確的私鑰以通過身份認證。
??下面我們了解一下瀏覽器與U2F設備之間的數據幀格式。3.1. 註冊請求消息
??註冊請求消息如圖4所示:
??消息中各字段含義如下:- challenge parameter [32 bytes]:是對由挑戰值組成的Client Data(後面會介紹,客戶端生成的一個JSON字符串)使用SHA-256算法得到32位摘要。
- application parameter [32 bytes]:對使用UTF-8編碼的應用ID(application identity)使用使用SHA-256算法得到32位摘要。
3.2. 註冊回應消息
??註冊回應消息如圖5所示:
消息中字段含義如下: - reserved byte [1 byte]:固定值0x05。
- user public key [65 bytes]:65字節的公鑰。
- key handle length byte [1 byte]:key handle用於定位私鑰,這裏使用1字節表示長度。
- key handle [length specified in previous field]:key handle的值。
- attestation certificate [variable length]:使用X.509 DER格式的證書(有點類似於廠商提供的根證書),其中的公鑰用於驗證後面的簽名。
- signature [variable length, 71-73 bytes]:使用ECDSA算法的簽名值,使用ANSI X9.62 格式編碼。簽名的原文為:
- 一個為0x00的字節
- 請求中的application parameter
- 請求中的challenge parameter
- 上面提及的key handle的值
- 上面提及的user public key
3.3. 鑒權請求消息
??鑒權請求消息如圖6所示:
??消息中字段含義如下:
- Control byte (P1):取值可為3個值:0x07 ("check-only"),0x03 ("enforce-user-presence-and-sign"),0x08 ("dont-enforce-user-presence-and-sign")
- challenge parameter [32 bytes]:是對由挑戰值組成的Client Data(後面會介紹,客戶端生成的一個JSON字符串)使用SHA-256算法得到32位摘要。
- application parameter [32 bytes]:對使用UTF-8編碼的應用ID(application identity)使用使用SHA-256算法得到32位摘要。
- key handle length byte [1 byte]:1字節表示key handle的長度。
- key handle [length specified in previous field]:key handle的值。
3.4. 鑒權回應消息
??鑒權回應消息如圖7所示:
??消息中各字段含義如下: - user presence byte [1 byte]:0表示用戶不存在,1表示用戶存在。
- counter [4 bytes]:U2F設備鑒權計數,大字節序。
- signature:使用ECDSA算法的簽名值,使用ANSI X9.62 格式編碼。簽名的原文為:
- application parameter [32 bytes]:鑒權請求中的application parameter。
- user presence byte [1 byte]:上面提到的user presence byte。
- counter:上面提到的counter。
- challenge parameter [32 bytes]:鑒權請求中的challenge parameter值。
3.5. clientdata
??前面的請求/回應消息中對challenge parameter的構建使用到clientdata,clientdata為一個JSON對象字符串,其對象結構ClientData定義如下:
dictionary ClientData { DOMString typ; DOMString challenge; DOMString origin; (DOMString or JwkKey) cid_pubkey; };
??ClientData結構中各屬性含義如下:
- typ:註冊時使用值‘navigator.id.finishEnrollment‘,鑒權時使用值‘navigator.id.getAssertion‘ 。
- challenge:使用websafe-base64編碼(通常也叫urlbase64編碼,見RFC4648第5章)的字符串,由在線服務網站提供。
- origin: 網站標識。
- cid_pubkey:可選參數。
4 參考文獻
1.https://fidoalliance.org/how-fido-works/
2.https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/FIDO-U2F-COMPLETE-v1.2-ps-20170411.pdf
3.http://www.ietf.org/rfc/rfc4648.txt
FIDO U2F應用與開發(一)-原理與協議