在上一篇文章,我們已經掌握了DID的基本概念,接下來我們用一個具體的場景來看看DID是怎麼使用的。
0x0. 場景描述
小明是一個剛剛從大學畢業的應屆畢業生,在畢業當天學校頒發了畢業證給小明對應的數字身份,小明拿到畢業證後第二天去公司入職,其中一個環節,公司HR要求驗證小明的學歷信息,驗證完成,小明入職成功。
一般學校會頒發畢業證和學位證兩個證,這裏我們出於簡單起見,就把學位證忽略吧。
0x1. Holder小明生成DID標識和DID文檔
小明要想獲得學校頒發的畢業證,那麼他必須要有自己的DID,所以他先下載一個數字身份的手機APP,然後創建賬號。創建賬號的過程就是在手機中生成一個隨機是私鑰和對應的公鑰。這裏我們假設我們的DID標識的規則是“did:cid:身份證號”,所以小明在APP中輸入自己的身份證號碼,生成了一個DID標識:
did:cid:511112200001010015
同時也會生成一個DID文檔,內容如下:
{ "@context": "https://w3id.org/did/v1", "id": "did:cid:511112200001010015", "version": 1, "created": “2020-12-08T16:02:20Z", "updated": “2020-12-08T16:02:20Z", "publicKey": [ { "id": "did:cid:511112200001010015#keys-1", "type": "Secp256k1", "publicKeyHex": "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71" }, { "id": "did:cid:511112200001010015#keys-2", "type": "Secp256k1", "publicKeyHex": "e3080168ee293053ba33b235d7116a3263d29f1450936b71" } ], "authentication": ["did:cid:511112200001010015#key-1"], "recovery": ["did:cid:511112200001010015#key-2"], "service": [ { "id": "did:cid:511112200001010015#resolver", "type": "DIDResolve", "serviceEndpoint": "https://did.studyzydemo.com" } ], "proof": { "type": "Secp256k1", "creator": "did:cid:511112200001010015#keys-1", "signatureValue": "QNB13Y7Q9...1tzjn4w==" } }
這裏我們爲該DID設置了兩個公鑰,一個是小明自己的,用於認證簽名等,Key2是系統託管的,用於手機丟失或者系統崩潰導致用戶私鑰丟失的情況下,幫忙小明找回自己的DID,綁定成一個新的公鑰。
Proof部分是小明自己用自己APP裏面的私鑰對該DID文檔的簽名。如果我們想進一步增強安全性,可以將proof部分改爲由公安機關進行簽名。
DID文檔生成完成後,APP會將該DID和文檔上鍊到區塊鏈存證,一旦上鍊完成,所有人都能夠查詢到小明的這個DID和文檔。這裏的區塊鏈我們一般都是一個聯盟鏈,並不是任意數據都可以隨意寫入的,所以小明必須是使用自己的身份證號經過驗證確實是本人後纔會上鍊,防止其他人冒用小明身份證號的情況。
0x2. Issuer學校頒發畢業證VC給小明
學校本身也有自己的DID,由於學校是教育系統裏面頒發的DID,所以規則和小明作爲中國公民的DID規則不一樣,比如學校的DID標識是:
did:cedu:uestc
這個DID不是學校自己簽名的,而是被教育部簽名的(教育部的DID是did:corg:moe),我們在區塊鏈中可以找到該DID對應的DID文檔如下:
{ "@context": "https://w3id.org/did/v1", "id": “did:cedu:uestc", "version": 1, "created": “2020-12-08T16:02:20Z", "updated": “2020-12-08T16:02:20Z", "publicKey": [ { "id": “did:cedu:uestc#keys-1", "type": "Secp256k1", "publicKeyHex": "3053ba33b235d7116a3e3080168ee293053ba33b235d7116a33053ba33b235d7116a3" }, { "id": “did:cedu:uestc#keys-2", "type": "Secp256k1", "publicKeyHex": "e293053ba3053ba33b235d7116a3263d29fe293053ba" } ], "authentication": [“did:cedu:uestc#key-1"], "recovery": [“did:cedu:uestc#key-2"], "service": [ { "id": “did:cedu:uestc#resolver", "type": "DIDResolve", "serviceEndpoint": "https://did.studyzydemo.com" } ], "proof": { "type": "Secp256k1", "creator": "did:corg:moe#keys-1", "signatureValue": "QNB13Y7Q9...1tzjn4w==" } }
所有認證過的高校的DID都是由did:corg:moe這個DID創建的,所以這相當於傳統的根CA,我們只需要信任這個DID創建的DID,就可以認爲是正規的高校。
繼續說回頒發畢業證VC,學校根據小明的學習情況(入學時間、畢業時間、專業、是否結業等信息)以及小明提交的自己的DID,生成VC如下:
{ // VC內容所遵循的JSON-LD標準 "@context": [ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1" ], // 本VC的唯一標識,也就是證書ID "id": "uestc/alumni/12345", // VC內容的格式 "type": ["VerifiableCredential", "AlumniCredential"], // 本VC的發行人 "issuer": "did:cedu:uestc", // 本VC的發行時間 "issuanceDate": "2010-07-01T19:73:24Z", // VC聲明的具體內容 "credentialSubject": { // 被聲明的人的DID "id": "did:cid:511112200001010015", // 聲明內容:畢業院校、專業、學位等 "name":"小明", "alumniOf": { "id": "did:cedu:uestc", "name": [{ "value": "電子科技大學", "lang": "cn" }] }, "degree":"碩士研究生", "degreeType":"工科", "college":"計算機學院" }, // 對本VC的證明 "proof": { "creator": "did:cedu:uestc#keys-1", "type": "Secp256k1", "signatureValue": "3044022051757c2de7032a0c887c3fcef02ca3812fede7ca748254771b9513d8e2bb" } }
這裏最主要的就是credentialSubject證書的內容和proof頒發學校給出的證明。這個VC生成後會傳給小明,小明可以選擇將這個內容存儲到自己的手機APP中,也可以選擇存儲到雲上,以後需要使用時再讀取。
0x3. Holder小明提交學歷證明VP給Verifier公司HR
接下來小明來到新公司入職,入職當天需要提交學歷證明給公司HR,於是小明基於上一步驟生成的VC再封裝一下,生成VP,VP的內容如下:
{ "@context": [ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1" ], "type": "VerifiablePresentation", // 本VP包含的VC的內容 "verifiableCredential": [{ "@context": [ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1" ], "id": "uestc/alumni/12345", "type": ["VerifiableCredential", "AlumniCredential"], "issuer": "did:cedu:uestc", "issuanceDate": "2010-07-01T19:73:24Z", "credentialSubject": { "id": "did:cid:511112200001010015", "name":"小明", "alumniOf": { "id": "did:cedu:uestc", "name": [{ "value": "電子科技大學", "lang": "cn" }] }, "degree":"碩士研究生", "degreeType":"工科", "college":"計算機學院" }, "proof": { "creator": "did:cedu:uestc#keys-1", "type": "Secp256k1", "signatureValue": "3044022051757c2de7032a0c887c3fcef02ca3812fede7ca748254771b9513d8e2bb" } }], // Holder小明對本VP的簽名信息 "proof": { "type": "Secp256k1", "created": "2010-07-02T21:19:10Z", "proofPurpose": "authentication", "verificationMethod": "did:cid:511112200001010015#keys-1", // challenge和domain是爲了防止重放攻擊而設計的 "challenge": "1f44d55f-f161-4938-a659-f8026467f126", "domain": "4jt78h47fh47", "jws": "eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5 XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqs LfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh 4vGHSrQyHUGlcTwLtjPAnKb78" } }
這裏比較簡單,只是簡單的提交整個畢業證全部內容,所以VP中只需要把VC簽入進去,最後proof的地方小明用自己APP裏面的私鑰進行簽名,表名這個VP是小明自己生成的即可。這個VP生成後小明需要將整個VP的內容提交給新入職公司HR。
0x4. Verifier公司HR驗證通過小明的VP
公司HR作爲驗證者在收到小明提交的VP後首先驗證Proof字段,保證VP是小明提交的,而且沒有被篡改。接下來提取出其中的VC內容,對VC進行驗證,驗證過程如下:
- 從proof的creator中獲得頒發者的DID:did:cedu:uestc
- 通過區塊鏈查詢到該DID的文檔,在文檔中有其創建人和公鑰列表,其中我們取keys-1對應的公鑰。
- 創建人是did:corg:moe,是可信的DID,所以它創建的DID都是可信的。
- 我們進一步的再用did:corg:moe去區塊鏈讀取DID文檔,並獲得其中的公鑰,使用該公鑰對did:cedu:uestc對應的文檔進行簽名驗證,確保其沒有被篡改。
- 驗證通過,我們再用did:cedu:uestc的公鑰對小明提交的VC進行簽名驗證,驗證通過,則說明這個證書確實是可信的UESTC頒發的。
- HR檢查VC中提供的內容,與小明提交的履歷上是否一致,檢查完成,進行下一步的入職手續。
以上驗證過程中我們至少需要進行三次簽名驗證。驗證VP是小明提交的,驗證VC是UESTC頒發的,驗證UESTC的DID是MOE創建的,而MOE是在驗證方系統可信列表中的,所以整個就保證了小明提交的證書的可信。
0x5. 小結
以上只是簡化版的DID從生成到申請VC再到驗證VP的過程,實際生產過程中還涉及到更多的關於雙方系統的校驗,防止身份被冒充,系統唄攻擊等細節的考慮,都沒有講到,下一節,我們將講到DID中的選擇性披露和隱私保護的方法。