区块链技术大量依赖于P2P网络,可以说没有P2P就没有区块链现在的发展。而区块链拥有去中心化的应用理论,所以对P2P的过程有着近似严苛的安全要求。本文围绕P2P网络的基础架构以及安全协议展开论述。内容是通过我的大量文献阅读之后进行的提炼。希望大家多多交流!
P2P(peer-to-peer)网络又称为对等式网络,或者点对点网络。这是一种无中心的服务器、完全由用户群进行交换信息的互联网体系,P2P网络的每一个用户即是一个客户端,同时也具备服务器的功能。在P2P技术之前,我们所有的网络应用都采用C/S或者B/S架构来实现的,然而在之前C/S架构的应用程序中,客户端软件向服务器发出请求,服务器然后对客户端请求做出响应,在这种情况下,如果客户端越多,此时服务器的压力就越大。然而采用P2P技术实现的每台计算机既是客户端,也是服务器,他们的功能都是对等的。对于安装了P2P软件(如迅雷,QQ等)的计算机加入一个共同的P2P网络,网络中的节点之间可以直接进行数据传输和通信。
那么有读者可能会提问:那我传统的P2P架构与C/S或者B/S架构有什么异同点呢?
相比于C/S,P2P有其自己独特的优势:所有的客户端都能够提供资源,包括带宽、存储空间已经计算能力。所以其网络容量可以远超其他模式。具体来说:
P2P系统中的客户端能够同时扮演客户端和服务器的角色,使两台计算机之间能够不通过服务器直接进行信息分享。也就是说信息的传输分散在各个节点,无须经过某个中心服务器,用户的隐私信息被窃听和泄露的可能大大减少。
在C/S架构中,所有客户端都直接从服务器下载所有数据资源,这样势必会加重服务器的负担,而P2P则改变了以服务器为中心的状态,使每个节点可以先从服务器上个下载一部分,然后再相互从对方或者其他节点下载其余部分。采用这种方式,当大量客户端同时下载时,就不会形成网络堵塞现象了。
而C/S架构有下面的缺点:
1.服务器负担过重。当大量用户访问C/S系统的服务器时,服务器常常会出现网络堵塞等现象。
2.系统稳健性和服务器关联密切。指的是——如果服务器出现了问题时,整个系统的运行将会瘫痪。
解释了这么多内容,那么我们现在就将区块链中的P2P技术单独拿出来,具体的分析下其中蕴含的道理。
从技术方面来分析,区块链技术就是——P2P+共识机制+密码学。具体来说,区块链就是P2P的网络架构,通过密码学来保证数据的安全,通过共识算法来保证数据的一致性。对于其他架构来说,故障是不可避免的。但是对于区块链的分布式P2P网络来说,其基本不存在单点故障。就算节点频繁的进退也不会对整个系统产生影响。
而我们知道区块链的落地项目有许多,但是我们可以将这些内容大致的分为三类——公链、私有链、联盟链。而公链是具有完全开放的特性的,所以其决定了它不回在网络中采用P2P加密。而对于其余的两者来说(尤其是联盟链),其节点间互相合作却又不完全信任的情况使P2P网络显的尤为重要。
P2P 网络自身有多方面优点,在区块链的应用如下:
区块链的资源和服务分布在所有参与节点上,通过共识机制维护区块链网络一致性,无须中心系统的存在。
区块链节点可以自由加入、退出,网络系统根据节点自由扩展。
区块链网络没有中心节点,也就没有了攻击对象。参与节点分布在网络中,部分节点遭到破坏对区块链系统无影响。(我们知道许多协议均是依靠CA来进行处理的,这也就成为了许多黑客攻击的对象。然后区块链并没有CA这种机制,所以也就规避了风险)。
区块信息采用广播机制,无法定位广播初始 节点,防止用户通信被监听,保护用户隐私。
区块链通过限制节点连接数等配置,避免资源负载、网络阻塞。
针对区块链应用特点,按照 P2P 网络是否去中心化、节点地址是否结构化两个方面,将 P2P 网络分为如下四类。
在中心化网络中存在“中心服务器”,而其作用为保存接入节点的地址信息。倘若两个peer之间想要进行通信,那么它们可以通过中心服务器进行对方地址的索要。例如:
将音乐文件与 保存文件的节点相互关联,用户查找某个音乐时,中心服务器告知储存节点地址,用户点对点连接以获得音乐。
由此可知,中心服务器是用来提供地址索引的(其他架构的中心服务器是提供所有的服务)。倘若其出现故障,那么整个系统就出现瘫痪了。
对小型网络而言,中心化拓扑模型在管理和控制方面占一定优势。但鉴于其存在的上述缺陷,该模型并不适合大型网络应用。
因为它没有中央索引服务器,每台机器在网络中是真正的对等关系,既是客户机同时又是服务器。
全分布 P2P 节点可以自由加入退出,并且没有中心节点, 节点地址没有结构化统一标准,整个网络结构呈随机图的结构, 无固定网络结构图。然而完全的自由意味着新节点无法得知 P2P 网络节点信息,从而无法加入网 络。全分布式 P2P 网络更加自由化的同时也带来节点管理的问题,节点频繁加入、退出使得整个网络结构无法稳定, 大量的广播消息不仅造成资源浪费,甚至会阻塞网络。
而比特币采用的就是这种 P2P 网络结构,全分布式使得任 何人任何节点都可以参与,非结构化使得节点间既可以通过区 块链 P2P 协议同步区块数据,又保持匿名隐私保护。
举例如下:
当一台计算机要下载一个文件,它首先以文件名或者关键字生成一个查询,并把这个查询发送给与它相连的所有计算机,这些计算机如果存在这个文件,则与查询的机器建立连接,如果不存在这个文件,则继续在自己相邻的计算机之间转发这个查询,直到找到文件为止。为了控制搜索消息不至于永远这样传递下去,一般通过TTL (Time To Live)的减值来控制查询的深度。
全分布式最大的问题在于节点地址管理,节点间没有固定规则约束,无法精确定位节点信息,只能通过洪泛查询方式进行查找,对网络的消耗很大。而结构化网络采用分布式哈希表 (distributed Hash table, DHT),通过如 Hash 函数一类的加密散列函数,将不同节点地址规范为标准长度数据。
结构化模型与非结构化模型相思,但结构化模型的节点管理有固定结构图。例如:
以太坊将节点椭圆加密算法的公钥转换为 64 Byte 长度的 NodeID 作为唯一标志符来区分节点,使得以太坊可以在没有中心服务器的情况下实现节点地址精确查找。
结合中心化和分布式模型各有的优点,半分布式 P2P 网络
将节点分类成普通 节点和超级节点,从而构成了半分布式网络结构。
超级节点维护部分网络节点地址、文件索引等工作,超级节点共同实 现中心服务器功能。超级节点本身却是分布式,可以自由扩展退出,具备分布式网络优点。
超级账本 hyperledger fabric 采用的 P2P 网络结构就如此。其将节点分为普通用户节点和超级节点(排序、背书节点等)。超级节点可以由普通节点选举,也可以自行配置,单独一个超级节点停机不影响系统运行。
我们在上面的内容中介绍了P2P网络中的几种类型。下面我们详细介绍下关于区块链中的具体安全加密算法。
在描述协议前,我们先讨论下我们为啥们要使用P2P加密?
我们在区块链的节点之间、客户端之间需要建立安全的加密隧道,并防止在信息传输的过程中将敏感信息暴露给外人。除此之外,其也可以减少网络安全监管工作,提高安全性。
简单来说,在比特币“钱包”的应用中,早起其应用使用了SSL进行客户端之间数据的加密。而SSL/TLS可以结合HTTP协议组合成HTTPS来加密web的内容,也可以与一些常用的FTP等协议进行组合来保证P2P网络中应用数据层的安全。
具体来说如下:
1. 客户端发出一个 client hello 消息,携带的信息包括:
所支持的SSL/TLS 版本列表;支持的与加密算法;所支持的数据压缩方法;随机数A;
2. 服务端响应一个 server hello 消息,携带的信息包括:
协商采用的SSL/TLS 版本号;会话ID;随机数B;服务端数字证书 serverCA;
由于双向认证需求,服务端需要对客户端进行认证,会同时发送一个 client certificate request,表示请求客户端的证书;
3. 客户端校验服务端的数字证书;校验通过之后发送随机数C,该随机数称为pre-master-key,使用数字证书中的公钥加密后发出;
由于服务端发起了 client certificate request,客户端使用私钥加密一个随机数 clientRandom随客户端的证书 clientCA一并发出;
4. 服务端校验客户端的证书,并成功将客户端加密的随机数clientRandom 解密;
根据 随机数A/随机数B/随机数C(pre-master-key) 产生动态密钥 master-key,加密一个finish 消息发至客户端;
5. 客户端根据 同样的随机数和算法 生成master-key,加密一个finish 消息发送至服务端;
6. 服务端和客户端分别解密成功,至此握手完成,之后的数据包均采用master-key进行加密传输。
详细内容参考 SSL/TLS算法流程解析
然而,由于比特币官方的理念为“钱包”用户的身份应该是严格限定的,所以其在设计之初就保证了用户的身份是合法的,所以其SSL在后续的版本中并没有进行维护。
由于P2P之间的信息传递不可避免的要进行TCP连接,所以保证其连接的安全性是尤为重要的。然而我们如何保证会话的前向安全性呢?具体的算法流程是如何实现的呢?
站间协议(station to station)是秘钥协商方案,其基于经典的DH秘钥交换算法,提供了秘钥与实体的认证。
也保证了秘钥的前向安全性。
对于前向安全性,我们简单总结为:A与B之间的所有会话均有一个公共秘钥。但是假如我的这个公共秘钥丢失了那么我之前的所有会话均会被泄密。所以我们在每次会话过程中需要根据公共秘钥来生成一个“会话秘钥”,而需要根据这个会话秘钥来进行当前会话。
1 建立连接之前,A与B双方需要设置好共享的数据(Diffie-Hellman算法),包括双方的公钥、大素数n、发生器g
。
2 节点A生成随机数x,计算并将指数g^x发送给节点B。
3 节点B生成随机数y,计算指数g^y。
4 节点B计算共享秘钥 `K = (g^x)^y。
5 B计算(g^y , g^x),并用B的私钥签名,然后用共享秘钥K加密(这里是两层)。然后将密文、g^y
发送给A。
6 节点A使用B的公钥验证B的签名。
7 A将(g^x , g^y)使用A的私钥签名,然后用K加密,传送给B(跟步骤5相似)。
8 B用A的公钥验证信息的来源是否是A。
9 至此,A与B互相认证过,并且有共同的秘钥。之后就可以使用K进行会话加密。
由于传统的DH秘钥交换协议没有设计验证部分,所以很大可能会存在中间人攻击的情况。但是STS就很好的经过协商设计添加了对对方身份验证的过程,来避免了中间人攻击的可能。
而协议中使用密码学“离散对数问题”来保证其安全性。即正向计算C = F(M)
容易,但是在不知道秘钥K的情况下计算M = F^-1(C)
是困难的。
例如上述图中,a,b不泄露只是传递x与y的话,任何人是没有办法通过结果x,y来推出秘密a,b。
Sphinx是由学术研究者George Danezis和Ian Goldberg设计的一种协议,用于在一种点对点网络上转播匿名信息。这种解决方案于2009年5月首次被提出,最初与闪电网络甚至比特币没有任何关系。闪电实验室的Olaoluwa Osuntokun意识到Sphinx可以被利用,他与Blockstream的Christian Decker合作对这种协议进行了修改从而更好地适配闪电网络。
Sphinx与著名的匿名化通信工具Tor(洋葱路由)具有很多相似之处。与Tor一样,使用Sphinx发送的所有数据包都可以进行加密——包括接收的IP地址。然后这种加密要进行好几次,直到产生多个‘加密层’(所以用‘洋葱’来比喻Tor)。
通过使用聪明的加密技巧,所有的加密层都被应用,从而每个沿着路由朝向最终加密包目的地的中介都只能打开一个‘加密层’。这一层会向中介展示要将这个加密包转向何处。(与Tor相比,Sphinx使用经过改进的加密算法,并创建了一种大小固定的数据包来更好地模糊路由中节点的位置。)
简单来说,Sphinx协议是中间传话的人并不知道起点和终点,它们只知道上一个人已经下一个人。
例如我们儿时在教室向其他人传纸条。假设两个人隔的很远,那么我传递纸条的时候要在中间经过许多人的手。但是我纸条的内容又不能让其他人看到,所以此时我就要想办法既能传出去,又不会泄露。
下面请看我分析。
假设A要给D传纸条,那么中间有 A B C D E。
这里要用到公钥的思想,假如我的ABCDE均会配合我传递信息。那么我A首先要计算路径,嗯,,A说:“我发现最近的传递方法是经过 B C D到E”。于是他就要开始处理自己的消息了。
假设消息为M。公钥分别为Pa Pb Pc Pd Pe。地址分别为Addr_a,Addr_b,Addr_c,Addr_d,Addr_e。
之后A进行倒序操作,先使用E进行处理。Pe(M)---对M用e的私钥加密。之后用D的消息处理。 Pd(Addr_e , Pe(M))........直到最后用B的私钥签名Pb(xxxxxxx)。
至此,A就可以将处理过的消息以此传递,首先给B,B解密后发现地址是C,所以B传递给C。C解密后给D.........直到到了E处,E解密得到消息。每个参与者只知道各自这一跳的前一个和下一个节点。
根据我们上述的内容可以知道,像比特币、以太坊这样的公链是需要节点自由进出的,所以其不存在使用P2P加密的可能。
但是比特币其匿名性不足的缺点区块链安全—匿名性以及隐私性
对于处理区块链隐私性的问题,现在比较有前景的解决方案是闪电网络 + Sphinx协议。
闪电网络的本质是在比特币主链外建立可以双向流动的微支付通道,币可以跨节点传递。将大量小额放到闪电网络上,减少主链的负荷并提高小额交易的速度。
闪电网络实现了一种基于称为Sphinx的方案的洋葱路由协议。该路由协议确保支付发送者可以通过闪电网络构建和通信路径,使得:
中间节点可以验证和解密其部分路由信息,并找到下一跳。
除了上一跳和下一跳,他们不能了解作为路径一部分的任何其他节点。
他们无法识别支付路径的长度,或者他们自己在该路径中的位置。
路径的每个部分被加密,使得网络级攻击者不能将来自路径的不同部分的数据包彼此关联。
不同于Tor(互联网上的洋葱路由匿名协议),没有可以被监视的“退出节点”。付款不需要传输到比特币区块链,节点只是更新通道余额。
而将Sphinx与闪电网络结合后,将网络中的数据包进行多次加密,闪电网络中间层只能打开相应的加密层,这一层主要是展示这个包的路由信息。这样就实现了在网络上隐藏详细的交易细节。
本稿为原创稿件,转载请标明出处。谢谢。