在上一篇文章中,我们以最简单的生成DID,颁发VC,验证VP流程介绍了DID的用法,但是在实际生活中,我们并不总是希望直接将整个证件VC亮给验证者看,比如我们去住酒店时,需要登记姓名、身份证号信息,但是如果我们直接把身份证给前台人员的话,前台人员就可以看到我们的民族、住址等信息,对于我们普通人来说,也许觉得没什么,那要是明星、公众人物去住酒店,那么可能前台人员就可能出于各方面的原因偷偷把住址信息记下了或者泄露到网上,给证照本人的生活带来各种麻烦。那么我们有什么办法呢?用户属性的选择性披露能够降低风险。

我们以小明从公安机关获得身份证VC,然后在住酒店时,只出示姓名、照片和身份证号,不对外暴露民族和住址(因为身份证编号里面已经有生日了,所以我们就忽略掉出生日期属性)为例,说明用户属性的选择性披露的处理过程。

0x0.准备知识1:默克尔树

关于Merkle Tree默克尔树的介绍,网上已经很多了,只要讲解比特币基本原理的应该都会讲到默克尔树。使用默克尔树的目的是为了能够将一个区块中的所有交易形成一个短小的指纹(默克尔根,哈希值),并将这个指纹放到区块头,任何对交易的篡改都会导致指纹变化。而我们使用默克尔树而不是直接将区块中所有的交易直接算哈希的原因是因为我们希望能够进行快速的简单支付验证(SPV)。

我们以4个交易组成的默克尔树为例,我们要验证Data2是否被包含在区块中,只需要给出:

  1. 要验证的原始数据:Data2
  2. 要验证的数据所在的位置索引:1 (索引以0开始,所以Data2的索引是1)
  3. 验证路径:[Hash1,Hash34]
  4. 默克尔根:MerkleRoot

通过这4个参数,我们就能确认Data2是否被包含在这棵树中了。

0x1.准备知识2:基于种子的无限序列

基于前面提到的默克尔树和默克尔验证,我们可以将用户的属性作为Data部分计算默克尔树,比如我们要对身份证上的属性构建默克尔树:

基于上面的默克尔树,我们可以只暴露生日,而不暴露其他字段,然后给出验证路径,从而证明生日数据的真实性。但是这里有个潜在的隐私泄露问题,就是我们会暴露Hash1,而攻击者是可以穷举所有民族数据,算出每个民族的Hash然后进行比对,从而得出我并不想暴露的”民族“属性。那么怎么办呢?最简单的办法就是我们为每个字段都加点”盐“。

用户在生成默克尔树之前,需要先生成一个随机的种子,并将这个种子数据保存下来,然后基于这个种子生成N个序列(N取决与我们默克尔树的叶子节点数),因为我们的种子是随机生成的,所以我们可以认为这个序列也是随机的。最简单的办法就是用哈希函数,不断的对上一个数据进行Hash,从而得到下一个数据。以下是我的序列生成函数:

func GenerateSequence256(seed []byte, count int) [][]byte {result := [][]byte{}current := seedfor i := 0; i < count; i++ {current = getHash(current)result = append(result, current)}return result
}func getHash(input []byte) []byte {h := sha256.New()h.Write(input)return h.Sum(nil)
}

有了这个无限长的随机序列,那么我们就可以将每一个默克尔树叶子节点加盐了,如下图所示:

现在我们Hash值都是加了盐后计算的结果,所以不可能再被碰撞出原始数据。

0x2.生成VC

基于上面的两个知识点,我们在准备VC数据时,除了给出证件中的每个属性外,还需要给出:随机种子seed,默克尔根,发证机关对默克尔根的签名。我们以身份证为例,那么公安机关颁发给我们的身份证VC如下所示:

{// VC内容所遵循的JSON-LD标准"@context": ["https://www.w3.org/2018/credentials/v1","https://studyzyexamples.com/identity/v1"],// 本VC的唯一标识,也就是证书ID"id": "vc511112200001010015",// VC内容的格式"type": ["VerifiableCredential", "Identity"],// 本VC的发行人"issuer": "did:公安部门ID",// 本VC的发行时间"issuanceDate": "2010-07-01T19:73:24Z",// VC声明的具体内容"credentialSubject": {// 被声明的人的DID"id": "did:cid:511112200001010015",// 声明内容:姓名、性别、生日、民族、住址等"name":"小明","gender":"男","birthdate":"2000-01-01","nation":"汉","address":"A省B市C区D街道xxx号",//接下来是种子数、默克尔根、公安的签名"seed":"23523865082340324","merkleRoot":"ea59a369466be42d1a4783f09ae0721a5a157d6dba9c4b053d407b5a4b9af145","rootSignature":"3066022051757c2de7032a0c887c3fcef02ca3812fede7ca748254771b9513d8e266","signer":"did:公安部门ID#keys-1"},// 对本VC的证明"proof": {"creator": "did:公安部门ID#keys-1","type": "Secp256k1","signatureValue": "3044022051757c2de7032a0c887c3fcef02ca3812fede7ca748254771b9513d8e2bb"}
}

这里我们需要注意的是对默克尔根的签名并不是在proof字段里面,而是在credentialSubject里面,proof里面的签名是对整个VC数据的签名,而rootSignature是公安机关对构造的默克尔树的根哈希进行的签名。

0x3.生成VP

接下来假如小明要去参加一个生日当天免费送礼品的活动,活动方要验证小明的出生日期,于是小明可根据上一步骤的VC,生成对应的VP,其中只暴露生日字段,其他身份属性不暴露,示例如下:

{"@context": ["https://www.w3.org/2018/credentials/v1","https://studyzyexamples.com/identity/v1"],"type": "VerifiablePresentation",// 本VP包含的VC的内容"verifiableCredential": [{"@context": ["https://www.w3.org/2018/credentials/v1","https://studyzyexamples.com/identity/v1"],"id": "vc511112200001010015","type": ["VerifiableCredential", "Identity"],"issuer": "did:公安部门ID","issuanceDate": "2010-07-01T19:73:24Z","credentialSubject": {"id": "did:cid:511112200001010015",//以下是要选择性披露的内容"birthdate":"2000-01-01",//以下是验证披露字段有效性的数据//数据在默克尔树中的索引"dataIndex":2,//本数据加盐的值"salt":"6b264354ed367ced527a86d38f75f9c3888bd3939f548cc48d93af435890b84a",//默克尔验证路径"merklesibling":"34b64151443c3124620bf4ff69a05e97d580f0878b374b8343c6a5c3d8223435 9d2b5b35ccb5bf18747c1f5dc05771c68ce613e6eb0c5f5ef77cec8ba3e9da67 bb82c63d4e21525125bf66a6724fbb4dcbded26aae2baa2633235dc12730016e",//默克尔根哈希"merkleRoot":"ea59a369466be42d1a4783f09ae0721a5a157d6dba9c4b053d407b5a4b9af145",//公安机关对默克尔根的签名"rootSignature":"3066022051757c2de7032a0c887c3fcef02ca3812fede7ca748254771b9513d8e266",//用的公安机关哪个Key进行的签名"signer":"did:公安部门ID#keys-1"},}],// 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..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78"}
}

这里我们给出了选择披露的字段“birthdate”,然后给出了要进行默克尔验证的几个必不可少的字段:

  • "birthdate":"2000-01-01”,要披露的原始数据内容。
  • dataIndex,披露字段在构架默克尔树时在叶子节的索引,因为我们这里按:姓名、性别、生日、民族、住址排序,所以生日的索引值是2.
  • salt,对birthdate这个字段加的盐,这个数据小明可以根据自己VC中的seed和dataIndex计算得到。
  • merkleSibling是进行默克尔验证所需的路径,以前面提到的4个Data为例,如果我们要算Data2的验证路径,那么就是Hash1,Hash34。
  • merkleRoot默克尔根,这个就不再累述。
  • rootSignature和signer是用来验证默克尔根的合法性的。merkleRoot、rootSignature、signer验证通过,则说明这个默克尔根是公安部认证过的。

0x4.验证VP

商家在收到用户提交的VP后,需要进行逐步的验证,主要包括以下步骤:

1.根据小明的DID从区块链中获取小明的DID文档,从中获得公钥,验证VP签名真实有效。

2.根据VC中的issuer,从区块链中获得公安机关的DID文档,从文档中获得公钥,另外也验证该DID是一个可信的DID。

3.根据公安部门的公钥,验证默克尔根的签名是否正确。

4.对披露字段、Dataindex、Salt、MerkleSibling、MerkleRoot等进行默克尔验证,保证披露字段是公安机关认证过的。

5.以上所有步骤验证通过,显示可信的披露内容:"birthdate":"2000-01-01”。

商家验证完成了小明的出生日期,但是并没有获得除了出生日期之外的其他身份信息,从而实现了选择性披露。

0x5.小结

以上我们讲解了在用户身份中具有多个属性时,用户只选择性的暴露其中某个属性,而且基于默克尔证明,给出了可信的证明字段,任何用户在收到VP后都可以进行合法性验证。同时我们基于随机种子生成了一个随机序列,并将随机序列作为盐添加到每个字段中,从而防止了潜在的默克尔验证时暴露的哈希值导致其他身份属性被碰撞的事情发生。

下一篇,我们更进一步的讲解使用零知识的方式证明小明大于18岁,但是却不暴露小明具体的生日。

去中心化数字身份DID简介——三、用户属性的选择性披露相关推荐

  1. 去中心化数字身份DID简介——五、DID的应用

    在上一篇文章中,我们给出了一种零知识证明的方法,解决用户身份属性的隐私问题,下面我们再来谈谈基于DID技术,我们都能在什么场景去应用. 0x.0 无密码安全登录 这个使用场景大家应该都很熟悉了,就类似 ...

  2. 去中心化数字身份DID简介——一、基本概念

    本人最近正在研究数字身份DID技术,该技术在区块链领域目前还比较冷门,并没有什么实际的应用案例,但是数字身份的应用场景广阔,是一个必然会火起来的技术.于是打算写几篇文章,好好讲一下其中涉及到的概念,技 ...

  3. 去中心化数字身份DID简介——二、一个完整的DID使用流程

    在上一篇文章,我们已经掌握了DID的基本概念,接下来我们用一个具体的场景来看看DID是怎么使用的. 0x0. 场景描述 小明是一个刚刚从大学毕业的应届毕业生,在毕业当天学校颁发了毕业证给小明对应的数字 ...

  4. 去中心化数字身份DID简介——四、用户属性的零知识证明

    在上一篇文章中,我们介绍了用户具有多个身份属性时,选择性的把其中的一个属性暴露出来,而不会造成其他信息的暴露.更进一步的情况,某些时候我们只需要验证用户的年龄达到多少岁,或者小于多少岁,但是并不关心用 ...

  5. 去中心化数字身份(DID)的灵魂绑定

    在元宇宙中的去中心化数字身份(DID)能够在各个平台.软件中实现一号通行,关键在于它与用户进行了深度灵魂绑定,使用户在进入不同平台时拥有高度可信度,从而不必像当前互联网中需要频繁地进行身份验证. 关于 ...

  6. Neutrino追问AMA第14期 | MYKEY CEO George:去中心化的身份系统是未来网络的一个核心基础设施

    在2月27日 Neutrino 追问 AMA 第14期交流中,我们邀请到了基于多条公有区块链的自主身份系统 MYKEY CEO  George Sheng 进行了一场关于<如何通过数字钱包降低使 ...

  7. 去中心化借贷Compound项目简介

    自从有了借贷,经济便开始以前所未有的速度增长.借贷体系需要某种形式的信任和中介,当前金融中介的角色由银行承担,但是我们有理由质疑当前借贷系统的各种缺陷,如强制性的筹资标准.获取银行服务的地理位置或法律 ...

  8. uPort:去中心化的身份系统试用

    uPort ( http://uport.me/ ) 是基于以太坊的去中心化身份系统,用于去中心化应用(Dapp).最近在以太坊测试网络上发布了测试版本. 下面介绍如何使用uPort. 注册申请,提交 ...

  9. Hyperledger Indy项目(开源去中心化身份平台)、去中心化身份(DID)、分布式数字身份项目

    文章目录 一.Hyperledger Indy 1. 什么是Hyperledger Indy 2. 名词概念 3. Indy实现独立的数字身份 4. Indy如何验证数字身份 5. 使用案例 Kiva ...

最新文章

  1. 第二章 基础查询 2-2 算术运算符和比较运算符
  2. 快速写出较好CSS的5种方法
  3. flowable 配置自定义表单_Flowable用代码自定义流程
  4. 睡觉觉睡觉睡觉计算机手机,孩子爱睡觉怎么回事
  5. java数组拼字符串_java数组、字符串拼接
  6. c语言课程设计平时成绩,计算中心
  7. console对象的方法log、info、warn、error的区别及几个实用的方法
  8. sql 孩子兄弟表示法 所有子节点_matlab实现随机+蓄意攻击网络节点(1)
  9. VC++设计简易计算器笔记(一)
  10. vue3.0引入ant-design-vue报错 export ‘default‘ (imported as ‘Vue‘) was not found in ‘vue‘
  11. 亲密关系-【认知情绪】-每一次生气的背后有什么
  12. 中联医疗系统服务器,中联电子病历系统(ZLEMR)
  13. 止增笑耳的星际迷航前传
  14. “欢迎来到智能城市,我是小武”
  15. Oracle全球化 —— 时间类型、时区与时间函数
  16. ROS学习(11)使用ROS创建地图
  17. Maestro Z实时无标记细胞分析仪,评估免疫细胞治疗效价
  18. 手机号登录和微信登录
  19. juniper常用命令
  20. Mentor Graphics Calibre 2017.1 Linux 1DVD寄生參數萃取

热门文章

  1. formvalidator4.1.3下载,formvalidator4.1.3下载地址,formvalidator4.1.3最新下载地址
  2. 指令集CEO潘爱民受仙桃大数据学院邀请,参与数据科学冬令营演讲
  3. IBM V3500存储恢复步骤实例(linux)
  4. 关于win10网络连接显示连接错误:错误代码720的解决方法
  5. 牛顿黏度定律【Newton's Law of Viscosity】
  6. ligerui列表显示
  7. 那些年,我们一起追过的Linux
  8. 1218直播节,花椒与北京卫视会密谋什么新局?
  9. java音频频谱,android获取和展示音乐的频谱
  10. 美容饮料俘获女性用户,是边喝边美还是鸡肋养颜?