微軟、 蘋果 跟 google 近幾年都在用力推 「無密碼登入」; 現在連 台灣的公部門跟金融業 也都在推動。 由 FIDO 聯盟 (Fast Identity Online) 推動的無密碼驗證機制, 背後到底是如何運作的呢?
可以先略讀 iThome fido2 名詞解釋, 對 FIDO 有點初步了解。 這篇 有更多 fido 相關名詞 (簡中版 沒註明原文出處); 不過本文只關心右圖最重要的這五個名詞: 所謂 「無密碼登入」, 當然就需要改用實體的金鑰登入。 這個實體安全金鑰稱為 authenticator, 可以是你的手機或 yubikey 之類的隨身碟金鑰, 或是電腦本身裡面的 tpm2 (搭配軟體) 。 想要登入的網站 (例如臉書或 gmail) 在這些相關文獻裡稱為 relying party, 簡寫為 rp ; 你上網用的瀏覽器稱為 client。 WebAuthn 定義了網站跟瀏覽器之間應該如何溝通; CTAP 則定義瀏覽器跟實體安全金鑰之間應該如何溝通。
無密碼登入的賣點之一是: 密碼不再存在網站, 所以可以避免 「黑帽駭客入侵網站伺服器取得許多用戶密碼」 這類的資安事故。 密碼不放在網站, 那放在哪裡呢? 如果只放在 authenticator 上面 (例如手機或電腦之類的 「硬體+作業系統」 裝置), 那麼這個密碼就稱為 resident key; 如果都不存 (例如 yubikey 之類空間不足的 authenticator), 那就稱為 non-resident key。 蝦米!? 不存密碼? 怎麼可能?
其實一直以來, 遵循資安規範的系統, 都沒有在存用戶的密碼啊! 請複習 單向雜湊函數。 較老的系統儲存密碼的雜湊值, 如果是太短或太常見的密碼, 有可能被 「彩虹表」 破解。 後來伺服器上改存 「加了鹽巴的密碼」 的雜湊值, 即使是太短或太常見的密碼, 黑帽駭客想要破解, 所需的運算量還是大到不切實際。
像是 yubikey 之類, 儲存空間有限的 authenticator 則是連密碼的雜湊值都不存, 卻又可以提供 non-resident key、 可以登入無限多個網站! 這個超讚的問答 提供了解釋; 我又根據它用圖片搜尋找到 (yubikey 的生產商) yubico 的解說。 大推取自 Yubico 的右圖! 簡單講, 關鍵是 (1) 每次登入同一個網站時都重新計算一次「針對此網站的同一對固定金鑰」 (2) 單向雜湊函數的特性。 圖中有幾項重要的資訊:
- 用戶註冊時, 網址資訊會附加到 AppID 裡面、 傳給用戶。
- 亂數產生器 (Random Number Generator) 會產生一個 (此 AppID 專屬的) 亂數, 稱為 nonce。 可以把它想成是 (產生金鑰時使用的、 第二層的) 亂數產生器的種子。
- 每一枝 Yubikey 有一個獨一無二的 device secret。
Device secret 有點像是主密碼、 像是 tpm2 的 endoresment key: 它從來不出面對外; 其他的金鑰都由它間接產生。 至於怎麼間接產生? 我也搜尋不到答案。 總之, 上述三項資訊餵給 HMAC 產生一把專門用於此網站的私鑰, 再從私鑰產生對應的公鑰。 私鑰又跟 AppID 再算一次 HMAC, 產生一個 MAC (message authentication code)。 (stackexchange 的回答做了一些簡化, 並且把這個 HMAC 結果稱為 authentication tag。) 然後 yubikey 會把專用於這個網站的 nonce 跟 MAC 串起來, 構成一個 key handle, 傳給網站儲存。 另外, 同時也會把公鑰傳給網站。
用白話說, 可以把 key handle 想成是 (用 blkid 可查詢到的) 檔案系統的 uuid 或是 (用 ip a 可查詢到的) 網卡 mac address。 只不過這個 "uuid" 或 "mac address" 裡面包含了 (公開的) nonce 資訊, 以及一些 "簽章過" 的資訊。
以上是用戶向網站註冊時發生的事。 以後當用戶想要登入網站時, 網站把 key handle 傳回給用戶、 yubikey 把 key handle 拆成兩半, 一半是當初專門為這個網站產生的 nonce, 另一半是 message authentication code。 有了 nonce 跟 AppID, 就可以重新計算出專門用於此網站的私鑰 (跟公鑰)。 至於這個 message authentication code 就是上面所說的 「"簽章過" 的資訊」。 當初用私鑰跟 AppID 計算 HMAC 原來是這個目的: yubikey 要把 AppID 傳給未來的自己, 所以用自己的私鑰確認 「這就是我當初看到的 AppID 無誤」。
於是, 這個 yubikey 可以登入無限多個網站; 對每個網站都採用不同的 nonce, 也就是對每個網站都採用不同的一對金鑰。 私鑰從來都不離開 yubikey, 卻又不必儲存, 因為私鑰是每次重新用 nonce 計算出來的, 而 nonce 存在網站那邊, 不需要花 yubikey 的儲存空間。 (腦容量有點小的) 貴哥我真希望人類的社交也可以這樣: 如果每一位跟我交談過的人所講的內容都可以不要佔據我的腦容量, 下次見面或打電話時我可以直接從他腦袋裡讀取我們的對話內容... 超棒的!
* * * * *
以上是根據密碼學原理的分析與解說。 以下是我個人的一些問題與猜想。
我有一個小小的問題: 要登入時, 網站怎麼知道這個用戶是誰? 要從一大堆已註冊用戶的 key handles 當中挑哪一個來回應給目前這個用戶? Yubico 的文章跟 stackexchange 的回答都沒有講清楚。 我的猜測是: 一旦 微軟推動的 TPM2 跟 google 推動的 WEI 普及, 每部電腦上的 tpm2 晶片就提供了用戶獨一無二無法借用的類身分證字號、 網站要求瀏覽器支援 WEI 也就造成上網幾乎等同於實名制。 註冊/登入某網站時, 用戶的電腦必然會先告知網站自己的身分, 網站也就可以拿這個身分來綁定/查詢 key handle。
可是如果用戶拿著一把 yubikey 在不同的電腦之間跑來跑去呢? 上面的猜測就失效; 也許此時就只有 resident key 才可以成功登入? 例如拿手機作為 authenticator 的情況? 對用戶來說, 可以從不同的電腦登入比較方便; 但是微軟/google/蘋果會願意支援 「不用手機而用 yubikey 跨電腦登入」 的方式嗎?
再來談談 (促使我開始爬文研究 fido2 的) 這篇: How Hype Will Turn Your Security Key Into Junk。 作者發現有些情況下網站 (relying party) 跟 「名為 "passkey"、 號稱提供無限組登入帳號」 的 authenticator 產品, 它們之間的互動會造成 authenticator 誤用有限的儲存空間, 進而失去了原始設計的好處。 請見該文文末的圖: 更精確地說, 當網站表達 "偏好" (preferred) resident key 而 authenticator 是空間有限的 yubikey 的時候, 作者認為此時 yubikey 應該要堅持做自己、 堅持提供 non-resident key, 因為它的儲存空間就很有限啊! Yubikey 不願堅持提供 non-resident key 的原因是什麼呢?
也很期待有讀者可以找到技術文件的某些段落來回答我這些問題...
沒有留言:
張貼留言
因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。