首稿件发在了先知社区中,由于原创稿件,所以我在之后引用到自己的博客中
原文链接为 https://xz.aliyun.com/t/2874
一、引言
提及区块链我们不得不想到“币圈”的那些事情。而提到数字货币我们又不得不感叹一下数字货币的优点之一——匿名性。对此,我从一下四个点进行切入,逐一为大家介绍“币圈”里关于“匿名”的是是非非。
- 比特币的匿名性
- 关于匿名性的CoinJoin方案
- Zcash中的匿名性
- 我们所未曾熟悉的“门罗币”
下面就请跟随我的文章,一点一点进入密码学与区块链中,来了解属于BlockChain的点点滴滴。
二、比特币的匿名性
1 比特币的地址与交易
众所周知,前一段时间发生的全国高校勒索病毒就是希望使用比特币作为勒索赎金。而为什么在这里使用比特币来代替现实中的直接转账呢?这里我们就可以提到比特币匿名性的优点了。
简单来说,比特币地址是一串由字母和数字组成的26位到34位字符串,看起来有些像乱码。通过区块链可以查到每个比特币地址的所有转账记录。比特币地址就是个人的比特币账户,相当于你的银行卡卡号,任何人都可以通过你的比特币地址给你转账比特币。
比特币地址是比特币网络中的ID或者账号,用于接收比特币。它就是一串符号,以1或3开头,包含27到34个数字或字母(不包括0, I), 例如:14qViLJfdGaP4EeHnDyJbEGQysnCpwn1gZ。比特币地址来源于密码学中的公钥加密。用户首先创建一个密钥对,它包括一个私钥以及由其衍生出的公钥。对公钥进行进一步运算,可得到比特币的地址;而私钥本质是一个随机数,用于比特币转账时的交易签名。比特币交易中所说的消费,指的是转移一 笔以前交易的比特币,给以比特币地址所标识的新所有者。一个典型的Alice向Bob转账比特币的场景是:Alice创建一笔交易,她首先用自己的私钥进行数字签名,表明自己对要转出的比特币拥有所有权,同时发出一个锁定“声明”——只有Bob的签名才可以拿出这笔比特币。随后,这笔交易被传送到比特币网络当中,成为区块链众多区块的一部分。从Bob的视角来看,他可以验证出Alice确实有这笔比特币的拥有权,同时使用自己的签名可以确认,这是一笔发给自己的收入支付。上述是比特币地址的密码学原理。
根据上述内容我们不难发现,比特币中所使用的“地址”并不是公开、易懂的简单地址。而是利用了密码学中非对称密码的算法。这样做可以将那些明文的地址转换为匿名性更强的地址。起到混淆的作用,也使公众无法直接查看到地址所属的用户。
具体来说,比特币的地址是如何生成的?它又有什么特点呢?首先我们要讲解一下比特币钱包地址的生成。
当用户加入区块链这个大家族的时候,“地址”就必不可缺。
1,首先用户会使用算法随机生成一个【私钥】,而这个私钥一般为256bit。由于私钥十分重要,所以用户也会将私钥安全的保存起来。
2,之后我们会使用SECP256K1算法将私钥处理生成【公钥】。(SECP256K1是一种椭圆曲线算法,通过一个已知『私钥』时可以算得『公钥』,而『公钥』已知时却无法反向计算出『私钥』。这是保障比特币安全的算法基础。)
3,使用哈希算法RIPEMD160对公钥进行处理得到【公钥哈希】。(由于哈希函数的特性,此算法也是不可逆的)
4,将一个字节的地址版本号连接到『公钥哈希』头部(对于比特币网络的pubkey地址,这一字节为“0”),然后对其进行两次SHA256运算,将结果的前4字节作为『公钥哈希』的校验值,连接在其尾部。
5,将上一步结果使用BASE58进行编码(比特币定制版本),就得到了『钱包地址』。
具体格式可参考文章神秘的比特币地址详解
由此我们得到如下图。
虽然我们不知道交易双方的具体地址,但是我们有上述生成的字符串地址也可以进行相关交易。
- 首先我们需要使用【私钥】对交易进行签名。
由于私钥是交易发起方所保存的,所以我需要利用私钥对我们的交易进行签名,用以证明是我本人发起的交易。
- 之后要将其【公钥】一并写入到交易中便于他人验证。
交易数据被广播到比特币网络后,节点会对这个交易数据进行检验,其中就包括对签名的校验。如果校验正确,那么这笔余额就成功地从“转出钱包”转移到“转入钱包”了。
2 比特币半匿名性
而有心的读者也已经发现,虽然比特币中使用了非对称加密算法,但是我的交易仍会被所有节点所查看。而研究表明,比特币可仍然可以通过那些看似随机组成的字符串来找到交易的发起方和接收方。可参考
比特币匿名性其实有迹可循找到“身份标示点”可轻易锁定目标
于是我们可以大胆的说,比特币是具有“半匿名性”的数字货币。
除了匿名性外,每个地址的隐私性几乎也是无法保证的。因为比特币的每一笔交易都会公开记录在区块链账本上,任何人都可以查阅。只要通过分析每个地址发生过的交易,就可以发现很多账号之间的关系。
比特币的交易是记录各个地址之间转移货币的数量,并且通常有一个或多个地址输入,对应一个或多个地址的输出。例如:A要支付10个比特币给B,而A具有3个地址,各有4个比特币(4+4+4 否则不够用)。不仅如此,当A给B转账后,A仍然需要找零的过程。
而这个交易会广播到所有节点并被保存下来。其他人可以根据此来推断A的初始地址与找零后地址的关系。不论A经过了多少次交易,生成了多少次地址。那我只要拥有系统中所有的交易记录就可以溯源找到你本来的A。
而下面,我们将针对这些半匿名性问题提出一些改进算法。
三、CoinJoin方案
CoinJoin原理相对比较简单,就是把不同用户的多个交易合并成一个交易。
外人从这种混淆过的交易中无法假定输入地址属于同一人所有,也不能确定货币的流向。用户可以进行多次CoinJoin操作,进一步隐藏交易的关系。
上述图片表示了原本比特币转账交易的简图。而下面我们表示一下CoinJoin的具体方法。
CoinJoin不需要改变比特币的协议,实施起来相对容易。目前为止,已经投入使用的方案较多是采用中间服务器(大的比特交易区则为中间服务器),需要CoinJoin用户在服务器上进行登记,由服务器聚合多个用户请求生成大的交易,经过各个用户进行签名后发布到比特币网络中来。然而事情并不是十全十美的,虽然我们使用这种方法可以达到混淆的目的,但是中间服务器可以掌握所有用户的输入输出地址,对于该服务器来说用户的隐私则一览无余。倘若中间服务器被攻破,那么我们所有的信息则就都被公开了。
(这就如同密码协议中所讨论的是否选择有CA的方案那样,CA作为一个中间管理者可以方便我们协议的执行,但是CA又会成为我们系统协议的漏洞点所在)
谈及CoinJoin的思想,我们就应该谈论下它落地的具体协议算法——Coin Shuffle。
混币(Coin Shuffle)是一个去中心化的隐私功能,它可以让用户快速高效地与其他用户的资金进行混合,在现有的用户账户和混币后的新账户之间创建随机的映射关系,从而实现完全匿名。
在这里我只点一下混币的概念,具体的算法内容我在以后的稿子中进行详细的说明。大家可参考混币原论文。
四、Zcash中的匿名性
Zcash是一个去中心化的开源密码学货币项目,通过使用先进的密码学技术提供交易隐私和可选择的透明性。Zcash支付被发布在一个公有区块链上,但是交易发送者、接收者和交易数额是保密的。
我们为什么要单独将Zcash拿出来谈论呢?这里就要说一下Zcash的特点。从上述文章中我们知道,比特币的匿名性其实并不是很好。所以Zcash利用了密码学中的“零知识证明”来增强交易的匿名性。
Zcash使用一个被称为 zk-SNARK的零知识证明架构,该架构是由我们的经验丰富的密码学家团队在近期的突破基础上开发的。这个框架允许网络在不公开交易参与方或者交易数额的情况下维护一个安全的账户余额账本。Zcash交易的元数据是加密的,而不是公开地展示交易参与方和交易数额,zk-SNARK被用来证明没有人进行欺骗或者偷窃。
除此之外,Zcash除了对隐私有极大追求的匿名功能外,也可以进行公开透明的交易,其操作类似于比特币,而与比特币最大的不同是Zcash给客户同时提供了透明地址和隐私地址以供选择,当你需要隐藏账户的资金时,则可以选择向隐私地址发送Zcash,如果你不需要将交易的资金隐藏起来,你也可以选择使用向透明地址发送Zcash的方式完成交易。
下面我们就详细的说明一下Zcash中所涉及的密码学知识以及协议内容。
零知识证明
“零知识证明”在我看来是密码学中非常有意义的一个发现。简单来说,零知识证明是证明者能够在不泄露任何有用信息的情况下,使验证者相信他知道的一个秘密。例如:A在PKU上学,而他想向B证明他事实如此,但是却又不想给B看他的录取通知书(比如通知书的照片太丑等原因emmmm),此时A用零知识证明就可以达到这个目的。
而零知识证明有一下三个条件:
完备性:如果证明方和验证方都是诚实的,并遵循证明过程的每一步,进行正确的计算,那么这个证明一定是成功的,验证方一定能够接受证明方。
可靠性:没有人能够假冒证明方,使这个证明成功。
零知识性:证明过程执行完之后,验证方只获得了“证明方拥有这个知识”这条信息,而没有获得关于这个知识本身的任何一点信息。
Zcash的零知识证明理论
上面我们介绍了零知识证明的具体内容,下面我们根据Zcash中的具体协议来分析。
在比特币的协议中,当A准备向B进行交易一张“支票”。那么B将生成一份新的同等金额的“支票”,而A中的支票进行销毁处理。而这个过程会被矿工进行记账处理,并发布给所有节点。
而Zcash为了增强匿名性,它拥有两种地址:z-地址与t-地址。其中t地址是公开地址(如同比特币中地址)而z地址是秘密地址。此时如果A要转账支票给B,要经过如下的过程:
-
1 ,A用自己的私钥对支票进行签名,并得到一串新的字符串r。此时我们用Z1代表A的支票。
-
2 ,而与比特币一样,B也需要新建一张支票(Z2),而Z2与Z1的代号并不相同。
3,当交易产生时,我们需要销毁原A的支票。但是与比特币不同的是,我们不是直接销毁Z1,而是引入了“作废文件列表”的概念。从下图可以看出,原先的A持有的支票仍旧存在,并没有消失,只是这张支票已经被记入“作废列表”。在确定资产所有权时要同时读取两个列表的信息,能确定Bob拥有资产所有权的判断方法是:作废列表中不存在B所持“支票”的代号。
简单来说,发票列表里的值是不会被删除的。当发票不能使用后直接记录在作废列表里即可。
而在具体的交易过程中,我们可以进行如下操作:
首先我们定义每个用户的私钥为PK1、PK2....PKn。
之后我们定义n个支票Note1=(PK1 , r1)、Note2=(PK2 , r2)........Noten=(PKn , rn)
为了达到匿名的效果,我们使用哈希函数对其压缩,使其不可逆。H1=HASH(Note1)、 H2=HASH(Note2).......Hn=HASH(Noten)
之后引入废弃集合的概念:
发票列表 | 废弃列表 |
---|---|
H1=HASH(Note1) | HASH(Z1) |
H2=HASH(Note2) | |
H3=HASH(Note3) |
上面的列表中代表我共产生了n个支票,Z1为支票标识,废弃列表中的Z1表示我第一张发票是作废无用的
当用户2要给用户4转移一张支票时,用户2会选择随机数r4并生成新的支票
Note4 = (PK4 , r4)
并将其密码传递给用户4。之后用户2将HASH(Z2)
与HASH(Note4)
发送给系统中所有的节点。并得到如下表格:
发票列表 | 废弃列表 |
---|---|
H1=HASH(Note1) | HASH(Z1) |
H2=HASH(Note2) | HASH(Z2) |
H3=HASH(Note3) | |
H4=HASH(Note4) |
这些过程均由矿工进行记账。因为资产只能有一份,所有矿工手里还有一个作废列表。Alice要同时广播自己的“发票代号”,录入作废列表中。发票代号也是加密的。所以矿工们能看到的信息其实是这样的。其中Alice的支票是原先存在的,Alice的支票代号r1和Bob的支票是在交易过程中被Alice广播的。
矿工们能获取的信息相当有限,但是这并不影响对矿工对交易有效性的判断。
判断的逻辑相当简单:矿工拿到A给的支票代号Z1,去作废列表中检索,假如作废列表中已经存在Z1,则证明Z1所对应的的支票早已失效;若作废列表中并不存在Z1,则证明Z1对应的支票仍旧有效,此时矿工把Z1录入作废列表中,把新生成的支票录入支票列表中。所以记账的过程就是对原有支票登记失效,并存入现有支票票的过程。
在这个过程中,我们不难发现,每笔交易矿工能接收到的东西只有一个发票代号,和一张新的发票,而且这两样东西都是被加密的。所以矿工并不知道转账双方是谁,也不知道转账金额是多少。
Zcash零知识证明具体算法
由于算法篇幅过长,我后续文章会将算法的具体数学公式推导列出。这里放上参考文档。SNARKs英文文档
零知识证明与zkSNARK
五、最强门罗币
根据我们上述内容所看,匿名性不是那么容易就达到的。那有没有真正可以做到匿名的数字货币呢?下面让我们看一看门罗币的介绍。
门罗币的匿名性主要是由其环形签名技术实现的。在十七世纪的时候,法国群臣向国王进谏时,为了不让国王追查到是由谁带头签名上书的,于是他们发明出了一种环形签名的方式,所有人的姓名按环形排列,自然的隐藏了签名顺序,从而做到无法追查源头。
对于匿名性来说,我们要做到以下两点才算合格:1,接收方不可追踪、2,发送方不可追踪
。而对于门罗币来说,以下三点是满足他匿名性的关键。
- 环签名 - 发送方,不可追踪
- 混淆地址 - 接收方,不可链接
- 环机密 - 交易金额的隐匿
环签名
大家联名上书提意见的时候,怎样让外界难以猜测发起人是谁?上书人的名字可以写成一个环形,环中各个名字的地位看上去彼此相等,因此难以猜测发起人是谁。假设,Alice 发送 5XMR(XMR 即门罗币) 给 Bob,设定混淆交易数量为5。网络在转账时会自动生成5笔5XMR的转账交易,除了Alice发送给Bob的这笔,另外的4笔都是用来瞒骗外界观测者的“诱骗交易”,这样达到隐匿发送方的目的。
地址混淆
混淆地址是为了打破输入输出地址之间的关联,以此隐匿转账的来去关系。每当发送者要发起一笔转账的时候,这笔资金不会直接打到接收方的地址,而是打到一个系统临时生成的地址。
Alice向Bob转账时,发送者Alice用接受者Bob的公钥私钥加上一些随机数,生成一个独一无二的、一次性的地址,系统给这个临时地址添加5XMR。观测者,包括Alice、Bob自己都能看到这个临时地址,但都不知道地址里的钱属于谁。那么Bob怎么知道有人给自己转账,怎么收到这笔钱呢?Bob的钱包会用私钥进行搜索功能,查看区块链上的临时地址是否有属于自己的钱。当Bob的私钥(仅有接收方Bob自己的私钥能够)识别出自己有权认领的临时地址,就能使用这笔钱。
环机密
Alice怎么告诉区块链网络转账金额是5XMR呢?在 RingCT 的交易中, Alice 不会直接公开给网络5XMR,而是提供一个数字rct,作为交易金额输出。rct= 随机数 + 5(真正的交易金额)。 随机数是用来为真实金额遮盖的,由钱包自动产生。网络可使用这个rct值去验证交易输入是否等于交易输出的金额,以确认没有额外的 门罗币被伪造产生。 然而,对于一个外部的观察者而言,无从得知实际交易金额。
可以参考文章门罗币基础技术介绍
六、总结
区块链是现在时代的热门话题,而对于我们信息安全的研究人员来说,如何使用密码学领域的知识来加强区块链的安全是我们需要研究的。本次文章我从比特币开始到门罗币,一步一步由弱到强分析了区块链不同应用的匿名性。文章中涉及到许多源码、英文文档的解读所以部分长篇幅的内容暂时没办法呈现,后续我会持续进行深度挖掘来为读者们呈现更精彩的区块链安全知识。
七、参考链接
文章是在笔者大量阅读以及自身思考后进行的总结,文中也参考了部分文章的知识,特此感谢!!
- 1 https://blog.csdn.net/jeason29/article/details/51576659
- 2 https://en.wikipedia.org/wiki/CoinJoin
- 3 https://www.jianshu.com/p/93b1ccf7f3e1
- 4 https://www.jianshu.com/p/93b1ccf7f3e1
- 5 https://www.jianshu.com/p/4cc80bd7f29e
有兴趣的话大家可以给我评论,技术无界限,欢迎多多讨论!