WeIdentity 规范文档

版本说明作者
V0.1.0完成整体协议框架张俊麒
V0.2.0完善流程,ER等张俊麒
V0.3.0添加选择性披露,Notification机制张俊麒
V0.3.1补充WeIdentity Document,增加CPT字段定义陈浩
V0.3.2描述修改张俊麒
V0.3.3补充图解及撤销部分实现张俊麒,胡朝新

1. 设计目标

目标说明
多中心分布式多中心的ID注册机制,摆脱对传统模式下单一中心ID注册的依赖
开源开放技术方案完全开源,面向政府、企业、开发者服务
隐私保护实体的现实身份和可验证数字凭证的内容进行链下存储。支持实体将信息最小化或者选择性披露给其他机构,同时防止任何第三方反向推测出实体在现实世界或其他场景语义中的身份
可移植性基于WeIdentity规范,数据可移植至遵循同样规范的其他平台,兼容业务主流区块链底层平台
互操作性提供标准化接口,支持跨链、跨平台互操作
可扩展性保证操作性,可移植性或简单性的情况下,数据模型可以通过多种不同方式进行扩展

2. 相关术语

详见:术语表

3. WeIdentity DID

WeIdentity DID与WeIdentity Credential的关系

weidentity-er.png从图中可见,WeIdentity DID与WeIdentity Credential的关系并非单纯的一对多:从设计目标上看,WeIdentity DID用来描述实体(人或物),WeIdentity Credential用来描述实体的身份、属性和实体间关系。因此,一个WeIdentity DID可以持有多个WeIdentity Credential;而一个WeIdentity Credential则会包含至少一个所描述的WeIdentity DID,可能会有多个。最后,每个WeIdentity DID都有一个WeIdentity Document,用来存储此DID的认证方式(如公钥、私钥套件)等信息,与WeIdentity Credential无关。

总体流程

overall-flow.png一般来说,WeIdentity解决方案的基本流程如下:

  1. 用户根据业务需求,选择是否需要进行KYC认证。
  2. 用户生成WeIdentity DID。
  3. 用户向相关业务方申请Credential。
  4. 相关业务方扮演Issuer的角色,发行Credential交给用户。
  5. 用户成为了Credential的Holder。
  6. 用户出示Credential,以完成业务需求。
  7. 相关业务方扮演Verifier的角色,验证Credential有效性。

如何生成WeIdentity DID

WeIdentity DID = did:weid:chain-id:bs-specific-stringweidentity-did-format1.png

字段说明
did遵循DID规范,固定前缀did
weidWeIdentity DID规范的method name字段,固定为weid
chain-id网络id,用于路由到不同的网络
bs-specific-string基于底层区块链平台生成,代表Entity在链上的地址,保证全网唯一

备注:bsSpecificString根据区块链底层平台和业务具体情况来确定生成规则,例如可以是随机字符串,或者区块链上的地址。

示例: "did:weid:1:0x0086eb1f712ebc6f1c276e12ec21"

WeIdentity Document格式

字段说明
@context用于描述WeIdentity Document结构等信息
idWeIdentity DID,表示当前Document描述的Entity,用于自描述
createdDocument的创建时间
updatedDocument的更新时间
publicKey公钥数组列表,格式如下
publicKey.id公钥的ID
publicKey.type用于指定signature suite
publicKey.owner指定控制对应私钥的Entity,遵从WeIdentity规范,如果为空,则表明owner是Document的id字段,如果是Credential类Entity,则owner一般是某用户
authentication用于Entity证明其与当前Document的关联性
authentication.type用于指定signature suite
authentication.publicKey用来验证签名的公钥,引用publicKey数组里定义的公钥
serviceservice描述数组,用于描述跟当前DID相关的服务,格式如下
service.idservice endpoint的ID
service.typeservice endpoint的协议
service.serviceEndpointserviceEndpoint列表,可以是URI或者一个JSON-LD对象
service.其他待定
recoveryWeIdentity DID私钥丢失后,可由本字段指定的WeIdentity进行公私钥重置。是否需要抽象一层合约层来实现待定
  • WeIdentity DID的Authorization机制由补充规范实现。示例:
  1. {
  2. "@context": "https://weidentity.webank.com/did/v1",
  3. "id": "did:weid:1:123456789abcdefghi",
  4. "created": "2017-09-24T17:00:00Z",
  5. "updated": "2018-09-24T02:41:00Z",
  6. "publicKey": [{
  7. "id": "did:example:123456789abcdefghi#keys-1",
  8. "type": "RsaVerificationKey2018",
  9. "owner": "did:example:123456789abcdefghi",
  10. "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
  11. }, {
  12. "id": "did:example:123456789abcdefghi#keys-2",
  13. "type": "Secp256k1VerificationKey2018",
  14. "owner": "did:example:123456789abcdefghi",
  15. "publicKeyHex": "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71"
  16. }],
  17. "authentication": [{
  18. // this key can be used to authenticate as DID ...9938
  19. "type": "RsaSignatureAuthentication2018",
  20. "publicKey": "did:weid:1:123456789abcdefghi#keys-1"
  21. }
  22. ],
  23. "service": [{
  24. "type": "drivingCardService",
  25. "serviceEndpoint": "https://weidentity.webank.com/endpoint/8377464"
  26. }, {
  27. "type": "padiCertificateService",
  28. "serviceEndpoint": "https://weidentity.webank.com/endpoint/8377465"
  29. }],
  30. "recovery": ["did:weid:1:2323e3e3dweweewew2","did:weid:1:2323e3e3dweweewew3"],
  31. }

WeIdentity DID支持操作

创建

创建一个WeIdentity DID(以及对应的WeIdentity Document)

读取/验证

通过WeIdentity DID读取到WeIdentity Document,并验证

更新

更新WeIdentity Document的相关属性

4. WeIdentity Credentials

角色和关系

roles-relation.png如图所示在WeIdentity生态中,存在着以下角色:

角色说明
User (Entity)用户(实体)。会注册属于自己的WeIdentity DID,申请Credential,并通过出示给相关业务方来使用之。
IssuerCredential的发行者。会首先验证实体对WeIdentity DID的所有权,其次发行Credential交给实体。
VerifierCredential的使用者。会首先验证实体对WeIdentity DID的所有权,其次验证Credential的有效性。
User Agent / Credential Repository用户(实体)在此生成WeIdentity DID。为了便于使用,实体也可将自己的私钥、持有的Credential托管于此。

场景

scenario.png上图展示了五个WeIdentity生态下Credential在不同角色间流转的场景:

  • 身份证明机构作为Issuer向用户发行「实名认证Credential」,政府机构作为Verifier在办理公共事务时对其进行验证。
  • 学校作为Issuer向用户发行「学历证明Credential」,公司作为Verifier在对候选人进行背景调查时对其进行验证。
  • 出入境机构作为Issuer向用户发行「签证Credential」,海关作为Verifier在出入境时对其进行验证。
  • 公司作为Issuer向用户发行「收入证明Credential」,银行作为Verifier在发放贷款时对其进行验证。
  • 商户作为Issuer向用户发行「优惠券Credential」,商户自己作为Verifier在对优惠券核销时对其进行验证。更多使用场景,可见: 使用场景文档

Credential结构

属性说明
@context用于描述Credential的字段信息等
id本Credential的ID,按UUID生成
issuerIssuer的DID,遵从WeIdentity规范
issuedissue日期
claimClaim的具体细节,数据结构由CPT定义,详见CPT介绍
claim.primeNumberIdx素数在素数表中的index
claim.typeClaim Protocol Type的ID,申请按序递增,例如中国内地驾照设置为CPT100
revocation撤销相关实现,待补充
signatureIssuer的签名列表,是一个数组,可由holder和issuer分别打上签名
signature.type签名类型
signature.created签名的创建时间
signature.creator签名机构的WeIdentity DID
signature.domaindomain
signature.nonce随机数
signature.signatureValue签名的具体value,对整个Credential结构中除去signature字段的其他字段做签名

区块链上的Credential结构

属性说明
id同上
type同上
issued同上
claimHashClaim结构内容的hash
revocation同上
signature同上
  1. {
  2. "@context": "https://weidentity.webank.com/vc/v1",
  3. "id": "dsfewr23sdcsdfeqeddadfd",
  4. "type": ["Credential", "cpt100"],
  5. "issuer": "did:weid:1:2323e3e3dweweewew2",
  6. "issued": "2010-01-01T21:19:10Z",
  7. "claim": {
  8. "primeNumberIdx":"1234"
  9. //the other properties in this structure varied according to different CPT
  10. },
  11. "revocation": {
  12. "id": "did:weid:1:2323e3e3dweweewew2",
  13. "type": "SimpleRevocationList2017"
  14. },
  15. "signature": [{
  16. "type": "LinkedDataSignature2015",
  17. "created": "2016-06-18T21:19:10Z",
  18. "creator": "did:weid:1:2323e3e3dweweewew2",
  19. "domain": "www.diriving_card.com",
  20. "nonce": "598c63d6",
  21. "signatureValue": "BavEll0/I1zpYw8XNi1bgVg/sCneO4Jugez8RwDg/+MCRVpjOboDoe4SxxKjkC
  22. OvKiCHGDvc4krqi6Z1n0UfqzxGfmatCuFibcC1wpsPRdW+gGsutPTLzvueMWmFhwYmfIFpbBu95t501+r
  23. SLHIEuujM/+PXr9Cky6Ed+W3JT24="
  24. }]
  25. }

Claim Protocol Type(CPT)注册机制

不同的Issuer按业务场景需要,各自定义不同类型数据结构的Claim,所有的Claim结构都需要到CPT合约注册,以保证全网唯一。所有的CPT定义文件(JSON-LD格式)可以从CPT合约下载。

  • CPT格式

    属性说明
    @context用于描述CPT等信息
    idCPT的编号,要保证唯一
    versionCPT的版本号
    publisherCPT的发布者的WeIdentity DID
    signatureCPT的发布者的签名
    claimClaim的格式定义
    created创建时间
    updated更新时间
    descriptionCPT的描述信息
  • CPT例子

  1. "CPT": {
  2. "@context" : "https://weidentity.webank.com/cpt100/v1",
  3. "version" : "v1",
  4. "id" : "CPT100",
  5. "publisher" : "did:weid:1:2323e3e3dweweewew2",
  6. "signature" : "BavEll0/I1zpYw8XNi1bgVg/sCneO4Jugez8RwDg/+MCRVpjOboDoe4SxxKjkC
  7. OvKiCHGDvc4krqi6Z1n0UfqzxGfmatCuFibcC1wpsPRdW+gGsutPTLzvueMWmFhwYmfIFpbBu95t501+r
  8. SLHIEuujM/+PXr9Cky6Ed+W3JT24=",
  9. "claim" : "",
  10. "address" : "重庆",
  11. "class" : "C1",
  12. "created" : "2010-06-20T21:19:10Z",
  13. "updated" : "2016-06-20T21:19:10Z",
  14. "description" : "中国内地驾照"
  15. }

cpt-er.png其中CPT为模板类,定义了Claim包含的数据字段及各字段属性要求。Claim为CPT的实例。Issuer将Claim进行签名,即可生成Credential。

Claim示例参考:

Claim实例

Credential操作

创建Credential

任何实体都可以issue一个Credential。

验证Credential

通过这个接口,一个Entity可以对一个Credential进行验证。

存储/提取Credential

Credential的holder可以转移这个Credential,或者提取完整的Credential私下存储。

撤销 Credential

Credential的Issuer可以撤销这个Credential。

选择性披露

如何为Credential生成签名

Issuer生成Credential签名的过程:

  • Claim中的每个字段计算生成一个对应的hash值。
  • 将Claim中的每个字段的hash值以某种形式拼接起来形成一个字符串Claim_Hash,然后跟Credential原有的其他字段组成一个新的用于计算hash的Credential结构。
  • 对这个包含Claim_Hash的Credential结构计算hash,得到Credential Hash。
  • 使用Private Key对这个Credential Hash进行签名,得到签名的值Signature。sign-credential.png

如何验证选择性披露的Credential

用户选择需要披露的字段集合(可以是一个或者几个字段,这个例子中是Field_1),需要披露的字段提供原文,其他字段提供hash值。将包含这个Claim结构的Credential披露给Verifier。下面是Verifier验证的过程:

  • Verifier从Credential提取用户披露的Claim字段。
  • Verifier对用户披露的字段分别计算hash(这个例子中是Field_1,计算出Field_1_hash),然后得到一个包含所有字段hash值的Claim结构。
  • 对这个Claim结构中的每个字段的hash值以某种形式拼接起来形成一个字符串Claim_Hash,然后跟Credential原有的其他字段组成一个新的用于计算hash的Credential结构。
  • 对这个包含Claim_Hash的Credential结构计算hash,得到Credential Hash。
  • 使用Credential的Signature和Issuer的public key进行decrypt,得到一个签名的计算值。
  • 比较Credential的Signature与签名的计算值,看是否相等,确认这个Credential的合法性。verify-credential.png

Credential撤销

撤销如何工作

Credential撤销机制利用了下面两点:

  • 任意大于1的整数 a,如果 a 不是素数,则 a 可以表示为一系列素数的乘积,且这个表示是唯一的(不考虑顺序)。参见:算数基本定理
  • 目前没有一个有效率的算法,对两个足够大的素数乘积得到的半素数(semiprime)进行整数分解。参见:整数分解WeIdentity 会公开一个大素数的文件,每个素数会有一个 index,供所有 Issuer 使用。Issuer 发行一个 Credential 的时候,就随机从这个大素数文件中选择一个素数,这个素数的 index 会作为这个 Credential 的属性之一。并把以往所有发行的未撤销的 Credential 的素数相乘,得到一个大数 Accumulator(每个 Issuer 会维护自己的 Accumulator),并将这个 Accumulator 公开供所有接入方查询。

Issuer 如何撤销一个 Credential

用这个 Credential 对应的素数去除 Issuer 自己的 Accumulator,将结果更新为新的 Accumulator。

Verifier 如何验证一个 Credential 有效(未被撤销)

用这个 Credential 对应的素数去除 Credential 的 Issuer 公开的 Accumulator,如果能整除,则表明是 Credential 是有效的(未被撤销)。before-revocation.pngafter-revocation.png

5. Authority Issuer注册

链上每个WeIdentity DID持有者(包括人,机构,或者物)都可以issue一个Claim,并打上自己的签名,但只有联盟链里面的权威机构才可以在公共合约注册成为Authority Issuer。每个注册为Authority Issuer的新成员需要联盟链内其他机构投票通过。

字段说明
versionversion描述
idAuthority Issuer的WeIdentity DID,符合WeIdentity规范的ID
nameAuthority Issuer机构的名字
created创建日期
updated更新日期
publicKeyAuthority Issuer公开的公钥列表
validCrenRefAuthority Issuer公布的自己的当前所有未撤销的credential的primeNumber字段的累加乘积

6. Notification

通用字段如下,根据不同的type,notification的payload结构不同。

字段说明
type通知的类型:register, update
weidnotification描述的实体的WeIdentity DID
payloadNotification机制里,用以描述业务相关信息的字段

WeIdentity DID注册事件的通知

当创建WeIdentity DID时,注册了该notification的机构会收到这个通知,表明有新的WeIdentity DID被注册。

字段
typeregister
  • payload结构:暂定为NULL。

WeIdentity DID属性修改的通知

当WeIdentity DID的属性有更新时,注册了该notification的机构会收到这个通知,例如public key改变或者其他meta data值改变。

字段
typedocument_mod,表示WeIdentity Document有修改
  • payload结构(此payload是一个数组,以支持多个属性变更的通知。):
    字段说明
    operationadd, update 或者 remove
    field变动的字段的key
    original原值
    new新值

Notification携带业务数据

用于传输小段数据,例如机构间传递Credential的明文可以通过这类通知,payload由机构双方自行约定结构。

字段
typetransportation

Notification订阅

支持对感兴趣的通知进行注册。依赖于实现。

7. 引用