DID研究的第一步就是为用户生成DID标识符, 在帮助文件
14.2 HTTP API · BSN中说明了计算方法,
在SDK代码中 com.reddate.did.sdk.util.DidUtils类提供了生成函数。
1 创建DID过程介绍
有两个方式创建DID, 一种是在服务端创建,然后返回给前端。 另一种是在前端直接创建。 BSN-DID服务支持这两种方法。
//使用服务端创建DID
DidDataWrapper didData = didClient.createDid(false);
String did = didData.getDid();
因为创建DID必须使用公私钥信息,为了安全起见,一般用户多选择在前端(本地)生成公私钥然后计算生成DID,而不会把公私钥发送到服务端去计算。开发者可按下述介绍在本地完成开发。
1)通过椭圆曲线算法Secp256k1生成两对公私钥信息;
2)保存私钥,指定主备公钥拼装Base DID Document,其内容如下示例:
{
"@context": "https://w3id.org/did/v1",
"authentication":
{
"type": "Secp256k1",
"publicKey": "28986472722394106073871327423452879123214061743224210681401278929598807211140001274507530324221923795865447680836742348963337343510229880669968499735858"
}
"recovery":
{
"type": "Secp256k1",
"publicKey": "9251971168042915941551574641987721503984542761641852064853964541181378832746959340151297908312616596971625573967556676367696067937171601766581709843378481"
}
}
3)通过base58(ripemd160(sha256()))算法生成DID标识符,其格式如下示例:
did:bsn:3wxYHXwAm57grc9JUr2zrPHt9HC
4)拼装DID Document内容,如下示例:
{
"did": "did:bsn:3wxYHXwAm57grc9JUr2zrPHt9HC",
"version": 1,
"created": "2021-05-20T16:02:20Z",
"updated": "2021-05-20T16:02:20Z",
"authentication":
{
"type": "Secp256k1",
"publicKey": "28986472722394106073871327423452879123214061743224210681401278929598807211140001274507530324221923795865447680836742348963337343510229880669968499735858"
}
"recovery":
{
"type": "Secp256k1",
"publicKey": "9251971168042915941551574641987721503984542761641852064853964541181378832746959340151297908312616596971625573967556676367696067937171601766581709843378481"
}
}
5)使用主私钥对DID Document内容进行Secp256k1签名,最终形成带有签名属性的DID Document,如下示例:
{
"did": "did:bsn:3wxYHXwAm57grc9JUr2zrPHt9HC",
"version": 1,
"created": "2021-05-20T16:02:20Z",
"updated": "2021-05-20T16:02:20Z",
"authentication":
{
"type": "Secp256k1",
"publicKey": "28986472722394106073871327423452879123214061743224210681401278929598807211140001274507530324221923795865447680836742348963337343510229880669968499735858"
}
"recovery":
{
"type": "Secp256k1",
"publicKey": "9251971168042915941551574641987721503984542761641852064853964541181378832746959340151297908312616596971625573967556676367696067937171601766581709843378481"
}
"proof":
{
"type": "Secp256k1",
"creator": "did:bsn:3wxYHXwAm57grc9JUr2zrPHt9HC",
"signatureValue": "zD5nt+P/Ga/CRG2hJU/SMRXy210CLdvATsxQdPxTEy9Mc9Y0OSFpE3Yu5k2+OjQKVOtu5of9VFbgO3Zljw/vQxs="
}
}
2 DidUtils类中函数解析
// 根据主备公钥拼装Base DID Document
public static BaseDidDocument generateBaseDidDocument(KeyPair primaryKeyPair, KeyPair alternateKeyPair)
//从一个完整的DOC中解析出Base DID Document
public static BaseDidDocument generateBaseDidDocument(final DidDocument didDocument)
// 根据base DID Document计算DID
public static String generateDidIdentifierByBaseDidDocument(BaseDidDocument baseDidDocument)
//含义没搞清楚
public static String generateDidByDidIdentifier(String didIdentifier)
//指定主备公钥DID,生成DOC
public static DidDocument generateDidDocument(KeyPair primaryKeyPair, KeyPair alternateKeyPair, String did)
关键的是看这两个函数:
/**
* Generate base did document
*
* @param primaryKeyPair
* @param alternateKeyPair
*/
public static BaseDidDocument generateBaseDidDocument(KeyPair primaryKeyPair, KeyPair alternateKeyPair)
throws Exception {
BaseDidDocument baseDidDocument = new BaseDidDocument();
baseDidDocument.setContext(CurrencyCode.W3C_FORMAT_ADDRESS);
PublicKey primaryPublicKey = new PublicKey();
primaryPublicKey.setType(ECDSAUtils.TYPE);
primaryPublicKey.setPublicKey(primaryKeyPair.getPublicKey());
baseDidDocument.setAuthentication(primaryPublicKey);
PublicKey alternatePublicKey = new PublicKey();
alternatePublicKey.setType(ECDSAUtils.TYPE);
alternatePublicKey.setPublicKey(alternateKeyPair.getPublicKey());
baseDidDocument.setRecovery(alternatePublicKey);
return baseDidDocument;
}
/**
* Generate did identifier (encode the base did document after hashing twice)
*
* @param baseDidDocument
*/
public static String generateDidIdentifierByBaseDidDocument(BaseDidDocument baseDidDocument) throws Exception {
String baseDidDocumentStr = JSONArray.toJSON(baseDidDocument).toString();
// Coding base did with sha256
byte[] firstHashBaseDidDocument = SHA256Utils.getSha256(baseDidDocumentStr);
// On this basis, ripemd160 coding is carried out
byte[] secondHashBaseDidDocument = RipeMDUtils.encodeRipeMd160(firstHashBaseDidDocument);
// Finally, base28 coding is carried out
String afterEncodeBaseDidDocument = Base58Utils.encode(secondHashBaseDidDocument);
return afterEncodeBaseDidDocument;
}
上面代码说明了计算步骤, 第一步sha256计算hash,第二步RipeMd160计算hash,第3步Base58。
【特殊说明1】 Base58Utils类的算法有特殊性。 我测试了,同样的字符串,Base58Utils.encode的结果与一般的base58在线计算工具计算结果不一样。这一点什么原因就没有去分析内部代码啦。
【特殊说明2】 KeyPair生成公钥和私钥字符串也和一般的钱包工具生成结果不同。
一般的钱包工具生成的公私钥是16进制形式的字符串:
例如
私钥: 5fb92d6e98884f76de468fa3f6278f8807c48bebc13595d45af5bdc4da702133
而KeyPair生成私钥是: 59892406425224321141687523581481793923894983609789633294227503636425859954495
这个字符串是10进制的大整数,因此具体应用时要注意区分转换。
【特殊说明3】baseDocument中填写的公钥字符串是10进制的大整数, 切记不要搞错了。
3 测试代码
我写了一段测试代码,验证目的:
(1)手工拼装的baseDocument字符串与自动生成的字符串相同
(2)计算出did
//先生成两组私钥:
主私钥
privateKey 59892406425224321141687523581481793923894983609789633294227503636425859954495
publicKey 1648062039648339302524063279508895632770137069244278134081956539023412707736391318756182919431261356264811228156011285063580540937190422178407117759695197
备私钥
privateKey 99212890707702586423403586560516123688816915830506844876534947464669890270173
publicKey 4066670788180339434818057706073753563728493176529383949647043421305103177112833274244990482553429820005190263150190403413261964491159960007274805620197902
//测试代码
public static void createMyDid(){
DidDataWrapper didData = didClient.createDid(false);
String did = didData.getDid();
String baseDoc =
"{\"context\":\"https://w3id.org/did/v1\"," +
"\"recovery\":" +
"{" +
"\"publicKey\":\"4066670788180339434818057706073753563728493176529383949647043421305103177112833274244990482553429820005190263150190403413261964491159960007274805620197902\"," +
"\"type\":\"Secp256k1\"" +
"}," +
"\"authentication\":" +
"{" +
"\"publicKey\":\"1648062039648339302524063279508895632770137069244278134081956539023412707736391318756182919431261356264811228156011285063580540937190422178407117759695197\"," +
"\"type\":\"Secp256k1\"" +
"}" +
"}";
System.out.println("baseDoc = "+baseDoc);
String sha = SHA256Utils.getSha256String(baseDoc);
System.out.println("sha = "+ sha);
BaseDidDocument base = new BaseDidDocument();
base.setContext("https://w3id.org/did/v1");
PublicKey authentication = new PublicKey();
authentication.setPublicKey("1648062039648339302524063279508895632770137069244278134081956539023412707736391318756182919431261356264811228156011285063580540937190422178407117759695197");
authentication.setType("Secp256k1");
base.setAuthentication(authentication);
PublicKey recovery = new PublicKey();
recovery.setPublicKey("4066670788180339434818057706073753563728493176529383949647043421305103177112833274244990482553429820005190263150190403413261964491159960007274805620197902");
recovery.setType("Secp256k1");
base.setRecovery(recovery);
String baseDidDocumentStr = JSONArray.toJSON(base).toString();
System.out.println("baseDidDocumentStr = "+ baseDidDocumentStr);
sha = SHA256Utils.getSha256String(baseDidDocumentStr);
System.out.println("sha = "+ sha);
try {
did = DidUtils.generateDidIdentifierByBaseDidDocument(base);
} catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println("did = "+ did);
}
运行结果:
baseDoc = {"context":"https://w3id.org/did/v1","recovery":{"publicKey":"4066670788180339434818057706073753563728493176529383949647043421305103177112833274244990482553429820005190263150190403413261964491159960007274805620197902","type":"Secp256k1"},"authentication":{"publicKey":"1648062039648339302524063279508895632770137069244278134081956539023412707736391318756182919431261356264811228156011285063580540937190422178407117759695197","type":"Secp256k1"}}
sha = f1fbda792c9d7bcc09b0e8c9024ae68af09880e421f9a21313f6fd7e76c893a0
baseDidDocumentStr = {"context":"https://w3id.org/did/v1","recovery":{"publicKey":"4066670788180339434818057706073753563728493176529383949647043421305103177112833274244990482553429820005190263150190403413261964491159960007274805620197902","type":"Secp256k1"},"authentication":{"publicKey":"1648062039648339302524063279508895632770137069244278134081956539023412707736391318756182919431261356264811228156011285063580540937190422178407117759695197","type":"Secp256k1"}}
sha = f1fbda792c9d7bcc09b0e8c9024ae68af09880e421f9a21313f6fd7e76c893a0
did = 4SdogXgSRXdetxH28SdJM5dydtKd
大功告成,最后生成了DID: 4SdogXgSRXdetxH28SdJM5dydtKd
文章来源地址https://www.toymoban.com/news/detail-576287.html
文章来源:https://www.toymoban.com/news/detail-576287.html
到了这里,关于BSN-DID研究6--客户端生成DID的计算方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!