導 讀
別以為這是一個誘餌式標題,這篇文章是一篇乾貨文章,因此取這個標題是有深層次的技術原因的。
本標題的句式是一個疑問句,仔細看,其實包含2個問題:
1. 在數字時代如何成為一個有身份的人?
第一個問題答案是「普通的數字身份」。在看文章的各位其實都有一個數字身份,要麼是微信號,要麼是IP位址。
但你是否發現一個問題:這些數字身份並不是你真正擁有的,而是身份提供商分發給你的。IP位址是運營商分發給你的,隨時可以被運營商收走。微信號也是騰訊分發給你的,你知道帳戶密碼,但是伺服器更加知道。你選擇信任運營商信任服務提供商,信任他們不會隨意破壞你的身份,但這沒有技術保障。
2. 如何真正擁有身份?
是否有可能真正把帳戶掌握在自己手裡?
是否有可能登錄帳戶,但不告訴伺服器你的密碼是多少,卻還是能夠讓伺服器驗證你確實知道密碼,同時其他任何人都無法冒充?
答案是有。
本文將會進行介紹相關技術以及基於這些技術構建的Web3時代的數字身份技術:分布式數字身份(Decentralized Identity,DID)。
首先我們來回顧一下身份發展的歷程(如果想直接看技術原理的,跳到第二部分開始)。
身份發展的趨勢
在中國古代,身份最早出現在秦朝,當時商鞅變法,避免外國間諜的入侵,發明了照身帖(如圖1-1所示,可看到這個照身貼和我們現代的身份證相當接近,有頭像、姓名、戶籍等基本信息)。
之後身份技術在古代不斷發展,我們常在電視劇中看到過的虎符、免死金牌、玉璽、錦衣衛的牙牌,都是古代用於證明身份的技術。
圖1-1
到了現代,我國第一代身份證於1984年發布,此後不斷改進,不斷加入防偽技術。2004年發布了第二代身份證,並且加入了多重防偽技術。2013年,融合了居民的生物特徵。
我們發現,身份發展有兩大的趨勢:防偽和互通。
防偽這個趨勢很好解釋,身份本來就是為了證明「我是我」,防偽降低了「其他人冒充我」和「我冒充其他人」的概率。
而互通的原因是,人們往往同時擁有多個特徵及身份,指紋特徵、面容特徵,既有居民證明又有駕駛證明。
現代的數字身份也有類似的趨勢。
隨著信息技術的發展,數字身份開始出現,並先後湧現了中心化身份、聯盟身份(Federated Identity,1999)、用戶為中心的身份(User-Centric Identity,2005)、自主權身份(Self-Sovereign Identity,SSI,2016)這四個階段的身份。
這四個階段的發展的趨勢有3個:去中心化、互通、隱私保護。
去中心化:用戶個人對自己身份的完全掌控,只有自己知道密碼,只有自己有權限修改、讀取身份信息,身份權無法被任何其他機構剝奪。去中心化可以被理解為是一種終極意義上的防偽。防偽防到從技術上實現只有「我才能證明是我」。
互通:註冊一次數字身份,可以在其他服務商的任意數字服務上登錄。
隱私保護:用戶自己保管數據,從而能夠決定數字服務能夠調用哪些數據。
數字身份的發展趨勢比身份的發展趨勢多了一個隱私保護。
因為數字身份比較涉及到數據,而數據、隱私這個話題是目前非常熱門的一個話題。2020年10月21日,全國人大法工委就《個人信息保護法(草案)》公開徵求意見,意味著我國首部專門保護個人信息的法律不遠了。
分布式數字身份屬於第四個階段,其希望最終能夠提供實現自主權身份SSI的全部技術。有機構預測分布式數字身份的市場會在2017-2025年增長127倍,從5760萬美元達到73億美元,由此可見分布式數字身份的發展前途無量。
接下去介紹下分布式數字身份涉及的技術。
非對稱加密與數字籤名
前面提到過「不告訴伺服器你的密碼是多少,卻還是能夠讓伺服器驗證你確實知道密碼」的技術是存在的,這種技術被稱為零知識密碼證明(zero knowledge password proof),IEEE P1363.2定義了這種技術。
如果為零知識密碼證明進行分類,它屬於非對稱加密(public-key cryptography)的一種,而且IEEE認為它也是零知識證明的一種。
限於篇幅和行文目的,我們這裡只簡單介紹下非對稱加密,而不介紹零知識密碼證明的細節,二者原理是相通的。
非對稱加密是現代密碼學中非常重要的一個分支。一般的非對稱加密中用於認證用戶的不是密碼,而是密鑰,可以理解為了一個長度很長的密碼(如50個字符)。
密碼學主要是用於信息加密的,加密前的內容稱為明文,比如「ATTACK AT 6AM」,使用某個加密密鑰以及加密算法後,加密後可能變成了「NP7-UB-LDBUUB」,這個叫做密文。
要想從密文得到明文,必須使用解密密鑰以及解密算法。如果加密密鑰和解密密鑰相同,則為對稱加密;如果不同,則為非對稱加密。
非對稱加密的密鑰有一對2把,稱為公鑰和私鑰。
公鑰加密的內容,用私鑰可以解密;反之用私鑰加密的內容,公鑰可以解密。一般私鑰私藏,只有用戶自己知道;公鑰需要公布給其他人。這樣別人想要給用戶發送消息時,使用公鑰加密該消息,加密後的消息只有擁有用戶私鑰的自己才能解密,其他擁有公鑰的人無法解密。
非對稱加密主要是用於信息加密的,那如何用於用戶的認證呢?
數字籤名。
假設用戶A要證明自己是A,首先,構造一條消息「I AM A」;然後對該消息哈希函數運算得到哈希值H(I AM A),然後使用私鑰Priv對該哈希值進行加密,所得到的密文E(H(I AM A),Priv)即為用戶A對消息「I AM A」的數字籤名。
將消息原文「I AM A」和籤名E(H(I AM A),Priv)發給其他人,其他人使用用戶的公鑰可以解密籤名得到H(I AM A);然後也對消息原文進行哈希計算得到H(I AM A)』,如果H(I AM A)』== H(I AM A),說明發送「I AM A」消息的用戶的確擁有私鑰Priv,證明他就是用戶A。
總而言之,私鑰其實就相當於是用戶的密碼,而公鑰可以給伺服器用來驗證用戶是否真的持有私鑰,驗證的方式就是驗證數字籤名。
有了這個基礎,接下去就可以介紹分布式數字身份DID了。
分布式數字身份體系是基於非對稱加密和數字籤名建立起來的。
DID規範
分布式數字身份DID發展至今主要有5個技術規範:DID標識符(Decentralized Identifier)、DID文檔(DID Document)、DID解析器(DID resolver)、可驗證聲明(Verifiable Credential)、身份存儲庫(Identity Hub),這些技術規範的主要領導組織是W3C(World Wide Web Consortium)和DIF(Decentralized Identity Foundation)。
之所以有這幾個規範,其實也和身份系統本身的需求有關:
DID標識符:身份標識符的格式;
DID文檔:身份信息的格式;
DID解析器:身份信息的獲取,為身份認證(Authentication)提供了保障;
可驗證聲明:隱私數據披露的方式,為數據授權(Authorization)提供了保障;
身份存儲庫:隱私數據的管理;
根據Zcash創始人提出的標識符系統「Zooko三角理論」,標識符無法同時實現實現安全、去中心化、對人類有意義(易記憶)三者,W3C DID標識符主要考慮了安全、去中心化兩者。
此處的ALPHA 和DIGIT的在ABNF(Augmented Backus Normal Form)中有定義,而未在此ABNF中定義的其他語法在RFC3986中有定義,值得一提的是W3C DID標識符是符合W3C URI的規範的。
舉個例子:
did:ethr:0xE6Fe788d8ca214A080b0f6aC7F48480b2AEfa9a6
即為一個DID標識,其中ethr是method-name,指明了身份所在的域(此處ethr所指的域就是以太坊);0xE6Fe788d8ca214A080b0f6aC7F48480b2AEfa9a6是method-specific-id,表明了這個身份在域中的地址。
DID標識符只是表示一個身份的標識符,不包含身份的信息。而DID文檔就是用於描述身份詳細信息的文檔,一個DID標識符關聯到一個DID文檔。
DID文檔一般包含以下內容:
DID標識符(必須);
一個加密材料的集合,比如公鑰;
驗證方法集合;
一個服務端點的集合;
時間,包括創建時間和更新時間。
DID文檔的示例:
{ "@context": "https://w3id.org/did/v1", "id": "did:ethr:0xE6Fe788d8ca214A080b0f6aC7F48480b2AEfa9a6", "publicKey": [ { "id": "did:ethr:0xE6Fe788d8ca214A080b0f6aC7F48480b2AEfa9a6#controller", "type": "Secp256k1VerificationKey2018", "controller": "did:ethr:0xE6Fe788d8ca214A080b0f6aC7F48480b2AEfa9a6", "ethereumAddress": "0xe6fe788d8ca214a080b0f6ac7f48480b2aefa9a6" } ], "authentication": [ { "type": "Secp256k1SignatureAuthentication2018", "publicKey": "did:ethr:0xE6Fe788d8ca214A080b0f6aC7F48480b2AEfa9a6#controller" } ] }
其中@context欄位指明了該文檔的版本;id欄位指明了該文檔關聯到的DID;publicKey欄位指明了相關的公鑰;authentication欄位則引用了publicKey欄位裡存儲的公鑰,並組成了驗證該DID用戶身份的方式。DID文檔其實和傳統PKI系統裡的證書有點類似。
DID文檔實際格式可以是JSON,也可以是JSON-LD或者YAML、XML等。其存儲需要上鏈,或者至少哈希上鏈。
解析器的作用是通過DID標識符來獲取DID文檔,這樣,當DID用戶登錄某個服務時,該服務提供商調用解析器來獲取DID文檔,從而知道了如何來驗證DID用戶。
DID解析器的規範主要是DIF主導的。
DIF Universal Resolver的架構如下圖。其先通過DID標識得到該DID標識的method,然後去調用該method對應的Driver來完成最終的解析,這些Driver的具體實現不做限定,但是要遵循接口的規範。
DIF Universal Resolver可以認為是一個Driver聚合器。
之所以這麼設計架構,是因為不同DID的存儲是位於不同區塊鏈上,而且可能也是在不同的智能合約裡存儲的。用戶要使用DID,首先需要完成DID的註冊,而DID的註冊肯定是和某條區塊鏈(或者其它類型去中心化系統)關聯的,比如以太坊。
而且一般用戶也是使用一些DID Registry服務來完成註冊,比如以太坊上有uPort,uPort可以幫助以太坊上的用戶完成DID的註冊,如果是在其他鏈上可能有其他提供DID Registry的服務。
因此每個提供DID註冊的Registry服務可能是不同的。使用這種聚合器架構能最大限度地兼容所有的DID Registry。
圖3-1
接下去介紹DID的第四個技術規範可驗證聲明,其可能是目前DID生態裡最重要的規範。可驗證聲明Verifiable Credential,簡稱VC。
VC的目的前面說過,就是數據授權,而且是儘可能細粒度的授權,從而儘量降低隱私數據的洩露。
圖3-2
對某個東西的證明可以通過披露不同程度的隱私來實現,如圖3-2從左到右,隱私洩露程度降低。來看一個例子。
假設你今年24歲,如何證明你大於21歲?如果有三種選擇:
出示身份證
出示出生年月日
開一個大於21歲的證明
你會選擇哪種?
很明顯,這三種方案對你個人隱私的披露程度是不同的。
第一種對你隱私信息的洩露最大,而第二種其次,而第三種幾乎沒有洩露任何多餘的信息。
圖3-3
VC運行需要有一套機制,需要有很多角色。可以看到圖3-3裡有很多角色,這些角色的功能如下:
發行者(Issuer):能開具VC(能訪問用戶數據),如政府、銀行、大學等機構和組織。
驗證者(Verifier):能驗證VC,由此可以提供給出示VC者某種類型的服務,如遊戲網站、香菸店。
持有者(Holder):即用戶,能向Issuer請求&接收、持有VC,向Verifier出示VC,開具的VC可以存放在錢包裡,方便以後再次證明時使用。
標識符註冊機構(Registry):維護DID標識符及密鑰(DID文檔)的資料庫,如區塊鏈、可信資料庫、分布式帳本等。
VC的數據格式是什麼樣的呢?其大致會包含以下欄位:
VC的ID(必須);
VC的發行者;
聲明的主體內容;
聲明的證明。
時間,如發行時間。
一個實例:
{ "@context": [ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1" ], "id": "http://example.edu/credentials/1872", "type": ["VerifiableCredential", "AlumniCredential"], "issuer": { "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", "name": "Example University" }, "issuanceDate": "2020-01-01T19:73:24Z", "credentialSubject": { "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "alumniOf": { "id": "did:example:c276e12ec21ebfeb1f712ebc6f1", "name": [{ "value": "Example University", "lang": "en" }]}}, "proof": { "type": "RsaSignature2018", "created": "2017-06-18T21:19:10Z", "proofPurpose": "assertionMethod", "verificationMethod": "https://example.edu/issuers/keys/1","jws": "eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..TCYt5XsITJX1CxPCT8yAV-TVkIEq_PbChOMqsLfRoPsnsgw5WEuts01mq-pQy7UJiN5mgRxD-WUcX16dUEMGlv50aqzpqh4Qktb3rk-uQy72IFLOqV0G_zS245-kronKb78cPN25DGlcTwLtjPAYuNzVBAh4vGHSrQyHUdBBPM" }}
在這個VC中,@context欄位指明了這個VC的格式;id欄位指明了VC的id;type欄位指明了VC的類型;issuer欄位指明了VC的發行者;issuanceDate欄位指明了發行日期;credentialSubject欄位指明了VC的主體內容;proof欄位指明了VC的證明部分,可以被Verfier驗證。
這裡最重要的內容當然是credentialSubject和proof。
▲ 身份存儲庫
接下去介紹DID的第五個技術規範,Identity Hub。
首先我們要明確身份數據和隱私數據是不同的。身份數據是指公鑰這種只和這個帳戶相關的數據,而隱私數據是和用戶自己真實信息相關的數據如性別年齡等。
DID文檔裡只存儲和身份相關的數據;而Identity Hub就是用來存儲用戶的隱私數據的。Identity Hub,雖然是身份的Hub,但是存儲的是數據,可以理解為數據銀行。
我們習慣將資產放到銀行,為什麼?因為安全,銀行保證了我們資產的安全。同樣地,未來我們將數據存儲到數據銀行,可以保證數據的安全。
其有如下幾個特點:
Identity Hub是去中心化的、鏈下的個人數據存儲,可將對個人數據的控制權交給用戶。 它們允許用戶以安全而隱私的方式存儲其敏感數據,無用戶的顯式授權就無法獲取用戶數據。
Identity Hub實際在哪由用戶決定,可以是本地(手機、PC),也可以是雲端;
在未來,用戶將會把隱私數據存儲到Identity Hub,然後當應用服務調用用戶數據時必須請求用戶的同意才能獲取這些數據。
一個簡例:
來看一個簡例。將上面的內容都串起來。
假設小明有一個以太坊上的帳戶0x96f…3d4,小明想使用DID來登錄支持DID的遊戲網站A。
1. 小明找一個DID Registry服務(如uPort)幫其在以太坊上註冊一個DID :did:eth: 0x96f…3d4;
2. DID Registry服務將與該DID相關的DID 文檔(包含了公鑰等信息)存儲到以太坊鏈上;
3. 小明在遊戲網站A上使用註冊的DID登錄(遊戲網站A可以通過DID解析器得到DID 文檔,從而知道該DID的驗證方式);
4. 小明將其個人隱私數據存儲在多個身份存儲庫(Identity Hub),其中居民身份證上的隱私數據存在政府機構G,政府機構G也需要註冊好自己的DID身份的;
5. 在遊戲網站A上,小明想證明自己年齡>16歲從而獲得遊戲時間;
6. 小明向政府機構G(Issuer)請求開具一個自己年齡>16歲的可驗證聲明(Verifiable Credential,VC);
7. 政府機構G通過查詢小明的居民相關隱私數據發現小明確實>16歲,因此開出了這個VC(帶著G的籤名)給小明;
8. 遊戲網站A驗證這個VC的籤名,發現確實是政府機構G開具的選擇信任,從而發放遊戲時間;
9. 假如某一天,遊戲網站A倒閉了。此時小明的DID依舊存在,還可以用於其他應用(如遊戲網站B)的登錄。
總結
總結一下DID。
DID的提出是為了達到自主權身份。但是實際上是否能夠完成其目的呢?
從身份上看確實DID的方案是不錯的,將身份存儲在區塊鏈上,用非對稱加密的密鑰保證用戶對帳戶的完全控制。這部分確實DID做的不錯。
不過我們也很明顯能發現一些問題,主要是在數據存儲上。
在VC系統裡發放VC的Issuer其實還是掌握用戶數據的,因此VC的這個運轉架構本質上還是中心化和可控的,用戶必須要相信某些機構來託管隱私數據。但這已經比把這些隱私數據放在服務提供商的伺服器上要好太多。
而服務提供商(如4中的遊戲網站A)雖然沒辦法拿到用戶的隱私數據,但是用戶在服務提供商處產生的數據,比如小明玩遊戲產生的裝備、皮膚、等級,這些數據似乎還是被遊戲網站A牢牢掌控住了。
課後習題
1. 根據本文內容,以下關於「分布式數字身份」的描述,是錯誤的?
【A】分布式數字身份基於非對稱加密和數字籤名技術
【B】分布式數字身份屬於數字身份發展的第三階段
【C】分布式數字身份是為了實現自主權身份
【D】分布式數字身份可以實現個人真正擁有數字身份
2. 以下哪個字符串不符合W3C DID標識符的格式?
【A】did:btc:21tDAKCERh95uGgKbJNHYp
【B】did:btcr:xz35-jznz-q9yu-ply
【C】did:github:gjgd
【D】都符合
3. 以下說法正確的是?
【A】 一個DID文檔必須包含服務端點相關的信息
【B】 非對稱加密中使用公鑰加密的信息無法用私鑰解密
【C】對某個消息進行數字籤名過程是:先對該消息進哈希,然後使用私鑰進行加密
【D】我國第一代身份證於1994年發布
4. DID解析器收到did:abc:0x01的解析請求後,以下說法錯誤的是?
【A】 會調用 abc Driver進行解析
【B】 所調用的Driver一定是在區塊鏈上進行查詢
【C】Driver返回一個DID文檔
【D】DID文檔可以是JSON、JSON-LD等格式
5. 以下說法不正確的是?
【A】 可驗證聲明可以最低程度披露用戶的隱私
【B】 可驗證聲明的proof可以被Verifier用於驗證此聲明的有效性
【C】身份存儲庫主要是存儲用戶的隱私數據
【D】身份存儲庫必須是運行在雲上
答案都藏在文章裡哦
作者簡介
樓嵩
來自致力於「構建區塊鏈網際網路,打通價值孤島」的BitXHub團隊
研究方向:Web3+
本文用圖來源
圖1-1 :https://kknews.cc/zh-hk/history/y5jeaon.html
圖3-1 :https://medium.com/decentralized-identity/a-universal-resolver-for-self-sovereign-identifiers-48e6b4a5cc3c
圖3-2 :https://uniqueid.substack.com/p/verifiable-credentials-your-digital