概述
Hyperledger是一个旨在推动跨行业应用区块链技术的开源项目,由Linux基金会在2016年主导发起。Hyperledger Fabric是最初引入的两个项目之一,也是目前应用最为广泛的企业级联盟链技术。 区块链本质上是一个分布式共享账本,在实际应用中,它通常承载着诸如资产和交易之类的敏感数据,因此安全和隐私保护是两个非常重要的问题。Fabric作为联盟链的代表技术给出的解决方案如下:
在安全方面的措施是:
■确保通信的安全性,节点间的通信都支持用TLS来确保传输层的安全。
■对账本进行隔离,让账本只在参与共同记账的组织之间共享,而其他组织无权访问账本。
■区分参与实体(节点和应用程序客户端)的角色,为访问资源的操作设置严格的权限控制。
在隐私保护方面的措施是:
■实现私有数据(Private Data)的机制,解决在一个拥有多个参与组织的账本中允许某些隐私数据只在小部分组织间共享的问题。
■通过身份混淆(Identity Mixer)机制,实现交易发起者的匿名性以及不可追踪性(unlinkability)。
"不可追踪性"是指:当一个用户发送多笔交易时,无法从揭示出这些交易是发送自同一个用户。
任何技术的采用都是用来解决某类实际问题的,笔者力图将研究官网资料时那些感觉跳跃和晦涩的技术点解释清楚,做到知其然还知其所以然。限于篇幅,本文主要深入分析安全方面的解决方案,关于隐私保护方面的内容留将给下一篇文章来阐述。另外,文中难免有所疏漏和错误,欢迎各位读者指正。
01
通信的安全性
一个Fabric区块链网络的例子如下图所示。该区块链由Org1和 Org2两个组织的节点组成。两个组织都有Orderer节点,提供排序和出块服务。Peer节点有多种职责,在图中Org1的Peer1和Org2的Peer1承担了Endorser、Leader、Committer和Anchor这四种职责,Org1的Peer2和Org2的Peer2仅承担Committer职责。在节点之间会发生以下通信:
应用程序客户端发起交易时先访问若干个Endorser Peer节点去做背书。
然后应用程序客户端将背书结果封装成交易提交给任意一个Orderer进行交易排序、出块。
每个组织的Leader Peer从Orderer节点取回区块,经验证后写入本地账本。
组织内的其他Peer节点(Commiter)与Leader Peer节点进行账本同步,也是先验证再写本地账本。
组织间通过Achor peer进行数据同步(包括账本信息、节点信息、私有数据等)。
以上1~4步是有关交易的处理步骤。其中1、2、3步是基于gRPC协议进行通信;第4、5步是基于Gossip协议,其底层协议还是走gRPC协议。Fabric使用TLS(Transport Layer Security)协议来确保gRPC通信时传输层的安全性。具体原理如下:
■每个组织都有自己的TLS Root CA证书,这与其数据层的组织Root CA证书独立开来。
■每个节点(Orderer和Peer)都有自己的server TLS 证书,是由它所在组织的TLS Root CA签发出来的。
那么问题来了,Org1的参与实体(节点或应用程序客户端)如何与Org2的节点完成TLS握手呢?当Org2的节点把它的server TLS证书发送给Org1的实体时,接收方如何验证该证书?
答案是:Fabric会让所有参与通道的实体,都能共享到所有通道成员组织的TLS Root CA证书(以及Intermediate CA证书)。这就是所谓的Channel MSPs机制(请看Channel MSPs章节)。因此,Org1的实体获得了Org2的组织TLS Root CA证书,所以就能验证Org2节点的server TLS证书了。
另外,细心的读者可能会发现,在上图中没有画出Kafka和Zookeeper节点。这是因为它们不属于区块链节点,而只是排序服务的实现方式。但为了提高安全性,Orderer到Kafka之间的通信可以配置成TLS,不过这套证书可以不是由组织的TLS Root CA来签发。另外剧透一下,Fabric将来打算用Raft来替换Kafka,目前正在开发中。这无疑是件好事,因为在生产级的部署中需要至少4个Kafka和3个Zookeeper,这实在是有点重了。
Fabric节点可以支持TLS单项认证和双向认证,具体方法请参考以下链接https://hyperledger-fabric.readthedocs.io/en/release-1.3/enable_tls.html
02
账本隔离
用通道来隔离账本
Fabric区块链是一个由不同的组织共同组成的联盟链。在一条链上Fabric可以隔离出多个账本。那么是如何做到的呢?
如下图所示,一个Fabric区块链中多个不同的组织可以组成联盟。在联盟之下若干不同的组织建立了一个一个的通道,每个通道都有一个独立的账本,只有通道成员组织之间才能共享账本。从这个角度来看,通道机制可以保证在成员组织之间形成一个专有的私密网络,交易在其上以保密方式执行,而与外部的无关组织或个人隔离开来。
MSP
现在再来思考一下“只有通道成员组织之间才能共享账本”具体意味着什么?其本质上是指任意成员组织的应用程序客户端可以访问任意成员组织的Peer节点和Orderer节点来执行交易;以及,通道成员组织的节点之间可以同步账本。
此外,当访问Peer节点或Orderer提供的不同服务时,尽管访问者属于某个通道成员组织,但是针对不同的角色应有不同的访问权限限制(比如:只有组织管理员才允许修改通道配置)。因此,Fabric需要有一种管理通道成员关系的能力,主要包括以下几点:
能够认证和识别参与者的身份。
以通道为边界建立信任域(Trust Domain)。这样所有通道成员组织的各个参与实体(Principal, 即节点或应用程序客户端)之间可以相互通信和访问服务。
能够识别参与实体的角色。这样可以针对访问请求做相应的权限控制。
Fabric实现了MSP(Membership Service Provider)模块来支持以上各项能力。具体做法是,MSP基于PKI体系为通道成员组织和组织内的各个参与实体创建并管理了一组X.509证书和私钥(如下图所示),用它们来认证身份和角色,以及验证成员资格。从这个角度来看,MSP的含义也是这组证书和私钥的代称。
Fabric实现了支持密码算法可插拔的BCCSP模块(blockchain crypto service provider)。MSP使用的非对称加密算法是椭圆曲线数字签名算法(ECDSA),哈希算法是SHA-256。
■ 图中左边的Root CAs和Itermediate CAs表示数据层的组织CA证书,用于验证消息体内的签名者的身份,它与传输层的组织TLS CAs和TLS Itermediate CAs独立开来。
■Administrators是组织内拥有管理员角色的用户的证书。
■Keystore(Private Key)和Signing Certificate是由组织的Root CA签发为参与实体签发的证书和私钥,在这些信息只在实体的Local MSP中才有。
■想了解其他元素请参考以下链接https://hyperledger-fabric.readthedocs.io/en/release-1.3/enable_tls.html
Local MSP
Local MSP是指组织的参与实体(Peer节点、Orderer节点以及应用程序客户端)存在于本地的MSP信息。它至少包含了组织的Root CAs证书、组织的TLS Root CAs、实体自己的证书和私钥,以及组织的Administrators证书。通过Local MSP,当与其他节点通信时,实体可以用私钥对发送的消息进行签名以向对方节点表明自己的身份;也可以用来认证组织内的其他成员实体发送的消息,并对某些操作做权限控制。比如:Peer节点可以用Local MSP中的私钥对背书响应结果进行签名。再举个例子,应用程序客户端可以用组织管理员的身份在他的组织的Peer节点上安装智能合约。
Channel MSPs
那么如何通过MSP建立以通道为边界的信任域呢?
答案是:Fabric让各个通道成员组织的节点和应用程序客户端共享一个全局的Channel MSPs,它是所有通道成员组织的MSP的集合。每个通道成员组织的MSP中主要包括:组织的Root CAs, TLS CAs和Administrators证书。通过Channel MSPs,各个参与实体可以验证其他成员组织的参与实体的身份和角色,以及验证通道成员资格。
共享Channel MSPs的机制如下:
当通道创建成功后,Channel MSPs会被写入通道配置中(即账本的创始块)。当通道成员组织的Peer节点加入通道时会得到通道配置,因而获得了Channel MSPs。如下图所示。
Peer加入通道的过程实际上是由应用程序客户端以管理员身份先从Orderer取得账本的通道配置,然后传给该Peer节点。
图中没有提及的是应用程序客户端如何获得Channel MSPs,其实是通过Fabric SDK在初始化本地的Channel实例时,会连接到Peer节点获取通道配置,从中提取Channel MSPs。
身份验证
通过Local MSP和Channel MSPs,通道内的各个节点和应用程序客户端在传输层和数据层都可以相互验证身份。而来自通道以外的其他访问请求,因为无法通过通道成员身份验证而被拒之门外。以应用程序客户端请求Endoser Peer节点进行背书的过程为例(如下图所示),其发送的gRPC消息结构是一个SignedProposal类型,消息中包含对payload(即ProposalBytes)的签名(即Signature),在Proposal->Header->SignatureHeader中包含了用户证书信息。Endoser Peer用Channel MSPs中某个组织的Root CA证书来验证签名头中的用户证书,然后用用户证书来验证消息的签名,从而确定其用户身份以及是否具有通道成员资格。
03
访问权限控制
访问权限控制是Fabric中十分重要的功能,主要解决谁在某个场景下是否允许访问某些资源的问题。用户在与Fabric进行交互时,实际上是访问用户智能合约、系统智能合约或者是Event Stream Source(Eventing Peer提供的事件服务)等服务,这些服务都被视为资源。Fabric主要通过策略(Policy)来控制各种场景下访问这些资源的权限限制。Fabric实现了两种类型的Policy来满足不同的场景需求:
■Signature Policy: 用于明确指定哪些参与实体(Principal)必须签名,才能满足该策略。它支持AND, OR, 以及 NOutOf这样的策略组合。比如:"必须Org1和Org2的成员都签名",或者“在20个组织管理员中至少有11个人的签名”。
应用场景是:背书策略、智能合约实例化策略等。
■ImplicitMeta Policy: 它不像Signature Policy那么灵活,而是组合了多条子策略评估的结果,只有组合的结果满足给定规则(Rule),才能满足该策略。这种策略的描述形式是: "<rule> <sub_policy>"。默认支持的Rule有:ANY, ALL, MAJORITY。比如:"超过半数的通道内组织的管理员签名"(Rule则是:超过半数,子策略是:组织的管理员签名)。
应用场景是:用于配置管理相关的操作比如:通道创建策略、通道配置策略等,以及从Orderer读取通道配置的策略,或者访问Peer获取区块的策略等等。
关于Policy的官方介绍请参考以下链接
https://hyperledger-fabric.readthedocs.io/en/release-1.3/policies.html
现在拿背书策略和通道配置策略来分别举例说明。
背书策略
背书策略(Endorsement Policy)是一个典型的Signature Policy,Peer节点中的系统智能合约VSCC用它来检查交易中包含的背书签名否满足策略的要求。
VSCC(Verification System Chaincode)除了验证背书策略,它还检查交易信息的读集合中的每一个Key-Value Pair的数据版本是否发生了变化。
一个背书策略的例子如下所示:
OR(AND('Org1MSP.peer', 'Org2MSP.peer'), 'Org3MSP.peer')
其含义是只有当Org1和Org2都进行了背书签名,或者Org3进行了背书签名,这笔交易才能被认为有效。
在背书策略中有一个容易忽视的地方是:签名者身份(Identity)的表示形式是"MSP.ROLE",比如:'Org1.peer'。 那么是不是意味着,只认可组织Org1的Endorser Peer节点对背书结果的签名,而不认可组织Org1的其他类型的实体(比如:应用程序客户端)对背书结果的签名呢?
答案是:没错,'Org1.peer'表示只认可组织Org1的Endorser Peer节点的背书签名。
基于x.509证书的OUs属性,Fabric将签名者身份的证书进一步分为client和peer两种类型。将那些可以进行发起交易、查询Peer节点等操作的参与实体的身份归为client类型,比如应用程序客户端的用户证书;将那些可以进行背书或提交账本等操作的参与实体的身份归为peer类型,比如Endorser Peer节点和Committer Peer节点。
client类型的证书中的OU属性等于'client',而peer类型的证书中的OU属性等于'peer'。以下截取了Org1的Endorser Peer节点证书片段。
Certificate:
... content ommited ...
Subject: C=CN, ST=Shanghai, L=Shanghai, OU=peer, CN=peer1.org1.aaa.com
... content ommited ...
■Fabric v1.3支持通过配置config.yaml来生成client和peer类型的证书,详细内容请参考以下链接
https://hyperledger-fabric.readthedocs.io/en/release-1.3/msp.html
。当然,如果你是自己实现证书生成的功能并想做身份分类的话,请自行设置证书的OU为peer或者client。
■ Fabric v1.3还支持key-level的背书策略,它将覆盖智能合约级别的背书策略,有关更多内容请参考以下链接
https://hyperledger-fabric.readthedocs.io/en/release-1.3/endorsement-policies.html
通道配置策略
当向一个已有的通道中新增组织时,需要符合设定的通道配置策略,它位于账本的通道配置区块中。
通道配置策略是一种典型的ImplicitMeta Policy,该类型的策略不会直接进行签名检查,而是通过组合其配置层次中的子元素的策略(即子策略)来进行检查,然后根据Rule来判断策略是否满足。这里提到的配置层次可能让人费解,直接来看一下通道配置的数据结构吧,它构成一个树状层次结构,如下图所示。所谓”配置层次“就是指这个树状层次结构。
目前通道中已有了三个组织:Org1, Org2, Org3。通道配置策略的位置是:/Channel/Application/Admins。它是一个ImplicitMeta Policy类型的策略,Rule是"MAJORITY", sub_policy是"Admins"。它表示需要检查所有组织下名为"Admins"的子策略,并且超过半数的子策略都须满足。组织的"Admins"策略的位置是(以Org1为例):/Channel/Application/Org1/Admins。它是一个Signature Policy类型的策略,表示要求Org1的管理员角色签名。此时,如果Org4要加入通道,那么要求3个组织中,至少有2个组织的管理员签名才行。
Farbic v1.3已支持通过在configtx.yaml中设置访问控制权限,有关更多内容请参考以下链接
https://hyperledger-fabric.readthedocs.io/en/release-1.3/access_control.html
————————————————
原文链接:https://blog.csdn.net/w365904/article/details/100159932