2023年10月29日 星期日

圖解無密碼登入的 non-resident key 機制

微軟蘋果google 近幾年都在用力推 「無密碼登入」; 現在連 台灣的公部門跟金融業 也都在推動。 由 FIDO 聯盟 (Fast Identity Online) 推動的無密碼驗證機制, 背後到底是如何運作的呢?

fido2 名詞解釋 可以先略讀 iThome fido2 名詞解釋, 對 FIDO 有點初步了解。 這篇 有更多 fido 相關名詞 (簡中版 沒註明原文出處); 不過本文只關心右圖最重要的這五個名詞: 所謂 「無密碼登入」, 當然就需要改用實體的金鑰登入。 這個實體安全金鑰稱為 authenticator, 可以是你的手機或 yubikey 之類的隨身碟金鑰, 或是電腦本身裡面的 tpm2 (搭配軟體) 。 想要登入的網站 (例如臉書或 gmail) 在這些相關文獻裡稱為 relying party, 簡寫為 rp ; 你上網用的瀏覽器稱為 clientWebAuthn 定義了網站跟瀏覽器之間應該如何溝通; CTAP 則定義瀏覽器跟實體安全金鑰之間應該如何溝通。

無密碼登入的賣點之一是: 密碼不再存在網站, 所以可以避免 「黑帽駭客入侵網站伺服器取得許多用戶密碼」 這類的資安事故。 密碼不放在網站, 那放在哪裡呢? 如果只放在 authenticator 上面 (例如手機或電腦之類的 「硬體+作業系統」 裝置), 那麼這個密碼就稱為 resident key; 如果都不存 (例如 yubikey 之類空間不足的 authenticator), 那就稱為 non-resident key。 蝦米!? 不存密碼? 怎麼可能?

其實一直以來, 遵循資安規範的系統, 都沒有在存用戶的密碼啊! 請複習 單向雜湊函數。 較老的系統儲存密碼的雜湊值, 如果是太短或太常見的密碼, 有可能被 「彩虹表」 破解。 後來伺服器上改存 「加了鹽巴的密碼」 的雜湊值, 即使是太短或太常見的密碼, 黑帽駭客想要破解, 所需的運算量還是大到不切實際。

yubikey 的驗證機制 像是 yubikey 之類, 儲存空間有限的 authenticator 則是連密碼的雜湊值都不存, 卻又可以提供 non-resident key、 可以登入無限多個網站! 這個超讚的問答 提供了解釋; 我又根據它用圖片搜尋找到 (yubikey 的生產商) yubico 的解說。 大推取自 Yubico 的右圖! 簡單講, 關鍵是 (1) 每次登入同一個網站時都重新計算一次「針對此網站的同一對固定金鑰」 (2) 單向雜湊函數的特性。 圖中有幾項重要的資訊:

  1. 用戶註冊時, 網址資訊會附加到 AppID 裡面、 傳給用戶。
  2. 亂數產生器 (Random Number Generator) 會產生一個 (此 AppID 專屬的) 亂數, 稱為 nonce。 可以把它想成是 (產生金鑰時使用的、 第二層的) 亂數產生器的種子。
  3. 每一枝 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 的回答都沒有講清楚。 我的猜測是: 一旦 微軟推動的 TPM2google 推動的 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 的原因是什麼呢?

也很期待有讀者可以找到技術文件的某些段落來回答我這些問題...

沒有留言:

張貼留言

因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。