ddd009

ddd009

twitter

一文搞懂Dfinity的身份認證


標題:一文搞懂 Dfinity 的身份認證#

日期:2021-08-16 14:02:50

> 作者:ddd009
> 本文從基本的密碼學概念開始,詳細解釋了消息簽名認證的過程,最後講解了 Dfinity 是如何通過 Internet Identity 服務幫助用戶管理自己的身份(密鑰)的。

基本概念#

request

可以看到除了 canister ID,函數名稱等常規請求信息,請求內容還包括用戶的公鑰與消息簽名,Caller's Principal 是用戶的公鑰進行哈希得到的,下文中會具體講解這一過程。被調用方收到消息後會使用用戶的公鑰驗證簽名的正確性,並檢查公鑰與 Caller's Principal 是否對應。

而 canister 的開發者是不需要理會底層的密碼學細節的,只需要編寫代碼,Dfinity 會自動完成身份驗證。

principal

這張圖片展示了如何通過公鑰得到用戶的 Principal

首先從 DER 格式的公鑰開始,對其進行 SHA-224 哈希運算,得到一個 28 字節的字符串,之後添加一字節用於區分用戶 principal 和其他 principal,例如 canister 的 principal。

這 29 個字節是用戶 principal 的二進制表示,可以看到 Motoko 和 JS 中 principal 變量是一個 Uint8 的 Blob 數組,裡面保存的就是這 29 個字節

截屏 2021-08-16 上午 10.48.06.png

之後就是把這 29 個字節轉化為文本表示的過程,首先添加 CRC32 錯誤檢查碼,再進行 Base32 編碼,把最終得到的字符串以五個字符為一組分組,中間以 "-" 分隔,就得到用戶的 prinicpal 文本表示。

順便提一下,有base32 的社區實現 by flyq,已經合併到 vessel-package-set,可以通過 vessel 進行使用。

如果說用戶的 Principal 是與單一密鑰綁定的將會非常不方便。如果說你有多個設備,那你需要在這些設備中使用同一個密鑰,這即不方便又不安全。

Dfinity 使用了委託密鑰的機制,如圖你可使用黃色的密鑰對橙色的密鑰簽名生成一個委託,包含作用域與過期時間。而橙色的密鑰又可以對其他密鑰進行委託,所以說這一方式是非常靈活的。

delgation

看到這裡大家應該對於密鑰對,用戶 Principal,委託密鑰這些基本概念有了大概的認識,那麼 Dfinity 是如何使用這些密碼學技術來完成用戶身份驗證的呢?

委託簽名認證#

委託密鑰的一種應用與 Web Auth 有關,Web Auth 是 W3C 推出的最新標準,主要針對與 web 應用的雙重認證。也就是除了傳統的用戶名密碼外,用戶還需要對伺服器發出的質詢使用額外的安全設備進行簽名,密鑰是儲存在安全晶片中的,不會發生洩漏,即使你的系統感染了木馬,它們也不能對安全晶片中的密鑰怎麼樣。通過這種方式可以確保是用戶登錄了伺服器。

上面說的是傳統互聯網的做法,在 Dfinity 上這一過程有些許不同。使用中心化伺服器時,你可以與伺服器建立有狀態的長連接,因此只需要對伺服器發送的質詢進行一次簽名,之後的通信可以使用建立的連接傳輸。而在 Dfinity 上,並不存在一個中心化的伺服器,我們不能同服務間建立有狀態的連接,服務也不能主動向用戶發出質詢,因此用戶需要對發出的每一條請求進行簽名,而使用 Web Auth 時是需要對每次簽名進行確認的,我們當然不能每發一次請求就觸摸一下 Yubikey 或者按一次指紋,我們先生成一個短期的會話密鑰,再使用 Web Auth 對會話密鑰進行委託簽名,最後用委託密鑰自動完成對消息的簽名。這樣就解決了對多個消息簽名的問題。

Internet Identity#

儘管 Web Auth 非常適合安全的儲存密鑰,但是由於瀏覽器的安全限制,密鑰是與特定 canister 綁定的。在 IC 上只要 canister 不同就視為不同源,這種狀態分離對於安全性至關重要。而這也給用戶帶來了麻煩,例如你很難跨設備使用同一個服務。針對這一缺點官方推出了 Internet Identity,簡稱 II,類似於 Sign With Google 的 SSO 服務,方便用戶管理密鑰與身份

identity

如圖,應用前端生成會話密鑰並將公鑰發送至 II 服務,如果用戶同意,II 服務將對會話密鑰進行委託簽名,所有的認證過程都是在用戶端完成的。

image.png

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。