p { margin-bottom: 0.25cm; line-height: 120% }
a:link { }
Hyperleder Fabric系统架构核心逻辑包括MemberShip、Blockchain和Chaincode
p { margin-bottom: 0.25cm; line-height: 120% }
a:link { }
其中上述3个核心逻辑中,Membership服务用来管理节点身份、隐私、confidentiality 和 auditability。在一个 non-permissioned的区块链网络里,参与者不要求授权,所有的节点被视作一样,都可以提交一个transaction,去把这些交易存到区块(blocks)中。Membership Service将一个 non-permissioned的区块链网络变成一个permissioned的区块链网络,凭借着Public Key Infrastructure (PKI)、去中心和一致性。
从上面的描述中可以看出,对于一个隐私性要求较高,节点需要授权才可以加入区块链网络并节点可能存在不同角色的区块链我那个落,Membership从中起到授权用户、加密传输数据的作用。在Fabric 1.0版本中,MemberShip Service替换成fabric-ca模块。由于CA在pemissioned区块链网络中的重要作用,Fabric也将CA作为一个单独的模块,可以独立运行,其代码可从https://github.com/hyperledger/fabric-ca获取得到。
下面的图表描述了CA
服务器在Hyperleder
Fabric框架体系架构中的工作方式:
p { margin-bottom: 0.25cm; line-height: 120% }
a:link { }
_Hyperleder Fabric系统架构核心逻辑包括MemberShip、Blockchain和Chaincode
--> { }
p { margin-bottom: 0.25cm; line-height: 120% }
a:link { }
从表中可以看出,CA 服务器结构为树形结构,整个树形结构的根节点为根CA(Root Server),存在多个中间CA(Intermediate CA),图中每个中间CA服务器上可以配置一个CA服务集群,CA服务集群通过前置的HAproxy实现负载均衡。
Fabric CA提供了两种访问方式调用Server服务,一种是通过Client调用,另一种是通过SDK调用。两种调用都是REST风格的。本文使用的是通过Client调用。
接下来,参考fabric-ca官方文档说明要求,针对fabric-ca的请求/发放证书、注册节点等操作实践操作一遍已加深理解。
首先安装启动fabric
ca,启动fabric-ca可以通过docker和下载fabric-ca至本地启动两种方式,下文安装了fabric-ca在本地并启动:
本地启动fabric-ca的准备条件:
1、安装Go
1.7以上版本
2、正确配置了GOPATH环境变量
3、libtool和libtdhl-dev包已安装
通过运行命令:
go
get -u github.com/hyperledger/fabric-ca/cmd/...
上述命令可以安装fabric-ca-server和fabric-ca-client之$GOPATH/bin目录下
pre.ctl { font-family: "Liberation Mono", monospace }
p { margin-bottom: 0.25cm; line-height: 120% }
a:link { }
执行上述命令后,在GOPATH/bin下可以看到fabric-ca-server和fabric-ca-client已经正常启动了。
启动fabric-ca-server:
fabric-ca-server start -b admin:adminpw
其中-b参数提供了节点登记过程的引导节点,后面登记节点时需要用到。
使用命令fabric-ca-server start -b admin:adminpw --cacount 2启动了一个包含了2个CA服务簇的CA server
启动CA server后,在服务器根目录下分别新建了一个ca1和ca2两个文件夹,启动过程中服务器首先通过ecdsa SHA256算法生成密钥,然后编码生成CSR(证书签名请求,CSR签名请求中包含了请求用户的城市、公司等基本信息),CA服务器对CSR中的基本信息通过数字签名制作数字证书并颁发给申请者。上图可以看出最终生成的CA证书最终存储在ca1和ca2文件夹下的ca-cert.pem文件里。生成数字证书后,CA服务器会将证书信息写入到数据库或LDAP目录服务器中。上图中默认存放在ca1和ca2文件夹下的sqlite3 db中。
上图为执行服务器启动后生成的目录结构,其中fabric-ca-config.yaml是启动过程中所使用的配置文件。
切换到ca1文件夹下,通过openssl命令查看证书内容:
如图可以看到,数字证书包含了签名算法信息、申请者基本信息、申请者公钥信息等。
打开存储发放证书信息的sqlite3 数据库:
可以看到数据库中有3个表,其中users表中目前只有启动时设定的引导节点,还没有注册其他节点。certificates表中目前没有任何发放证书记录。
现在我们尝试使用fabric-ca先登记引导节点,命令如下:
fabric-ca-client enroll -u http://admin:[email protected]:7054
这里admin和adminpw即为fabric-ca-server启动时设置的引导节点登记id和密码
client执行结果如下:
server端接收到登记请求:
在ca-client目录下生成的目录结构如下:
其中msp/signcerts目录下存储的为client的数字证书,cacerts目录下存储的为证书链信息。
回到ca-server目录下,打开sqlite3数据库,可以看到刚刚颁发的数字证书已经记录在数据库里了。
接下来使用fabric-ca-client注册一个新的节点,这一步就是为fabric中的peer、user角色进行注册并登记的过程了,注册的命令为:
fabric-ca-client register --id.name admin2 --id.type user --id.affiliation org1.department1 --id.attrs ‘hf.Revoker=true,foo=bar‘
这里有两点需要注意:
1、--id.type参数必须是是server端配置文件里hf.Registrar.Roles属性值里的一个
打开fabric-ca-server的配置文件
其中通过hf.Registrar.Roles的属性值可以看出,客户端可以注册的类型有client,user,peer,validator和auditor
2、--id.affiliation这个属性表示:被注册对象的从属关系参数一定要归属于预先配置的组织属性。换句话说,被注册对象的affiliation参数一定要是预先配置的affiliation参数的一个前缀。例如,假设预先配置的组织关系为:“a.b.c”,那么新注册的对象的affiliation属性可以是“a.b.c”,也可以是“a.b”,但“a.c”就不能通过注册。
执行节点注册命令后,注册了一个user结点:
client端执行结果:
这里分配的password需要记住,后面在登记该节点时会用到。
server端接收到请求
登记刚刚注册过的admin2节点,登记命令为:
fabric-ca-client enroll -u http://admin2:[email protected]:7054 -M $FABRIC_CA_CLIENT_HOME/msp
这里登记时使用的erollId和密码就是上边注册过程中的节点名称和返回的密码信息。这册过程中也是可以指定密码的。
执行登记命令,结果如下:
打开fabric-ca-server的sqlite数据库
查看用户信息,其中有一个client节点admin和一个user节点admin2。其中admin是一个intermediateCA。
打开数据库表certificates,这是可以看到给admin2所颁发的证书已经记录了。
重新登记节点,在节点授权即将到期是需要重新登记节点信息。重新登记的命令为:
fabric-ca-client reenroll
重新登记过程重新发送签名证书请求,获取新的数字证书。
打开server端数据库,可以看到两条颁发给节点admin2的证书记录,两个证书颁发的时间不一样。
注销证书,注销证书的命令为:fabric-ca-client revoke -e <enrollment_id> -r <reason>
其中reason参数可以为:
1. keycompromise
2. cacompromise
3. affiliationchange
4. superseded
5. cessationofoperation
6. certificatehold
7. removefromcrl
8. privilegewithdrawn
9. aacompromise
10. unspecified
下面我们注销掉刚刚登记的admin2节点试一下,执行命令fabric-ca-client revoke -e admin2:
执行结果如下:
打开server端数据库:
可以看出admin2节点的证书状态已经改为注销了。
注册一个中间CA,具体命令为:fabric-ca-server start -b admin1:adminpw1 -u http://admin:[email protected]:7054
上述命令重新启动了一个CA服务器,作为引导节点CA服务器下的中间CA,执行结果如下:
服务端执行结果:
打开ca-chain.pem查看刚刚登记的中间CA服务器证书链:
可以看到证书链中包含上级CA证书和自己的证书信息。
尝试在刚刚建立的CA上注册登记一个节点,注册一个节点admin2的命令同上:
首先登记节点:
fabric-ca-client register --id.name admin2 --id.type user --id.affiliation org1.department1 --id.attrs ‘hf.Revoker=true,foo=bar‘
注册的结果已经记录在数据库中:
最后登记节点,执行命令:fabric-ca-client enroll -u http://admin2:[email protected]:7055 -M $FABRIC_CA_CLIENT_HOME/msp
进入刚刚登记的节点目录,生成如下目录结构:
打开cacerts下面的证书链文件,可以看到刚刚登记的节点证书链包含两个中间CA的数字证书信息,在验证由该个树形CA服务器中一个中间CA节点所颁发的数字证书是否真实有效时,会按照证书链自下向上进行验证,直至到达根证书。
如果区块链网络中有多个链,每个链为了保证各自的隐私性存在各自的CA服务器,那么当一个用户同时拥有两个链的权限时,怎样同时具备验证两个链上的节点所拥有的CA证书呢?按照上边证书链的原则,一个节点注册登记到一个中间CA后,应该只能拥有该条CA服务器链上的证书链。这里为了解决这个问题,有一种方法是交叉认证,在fabric-ca中也有类似的操作方法,即通过Restful接口获取另外一个CA服务器上的证书链。
具体命令为:fabric-ca-client getcacert -u http://localhost:7055 -M $FABRIC_CA_CLIENT_HOME/msp
这里我们新建一个单独运行的CA服务器:
查看该根服务器的数字证书:
接下来,我们在上文登记的节点admin2上运行获取刚刚建立的CA服务器证书链命令:
执行命令结束后,查看admin2节点所对应的证书链目录:
可以看到启动在端口7056上的CA服务器所对应的证书链已经同步过来了。
Fabric-ca这个模块详细描述了CA工作过程中使用fabric-ca-client和sdk方式的方法,其中包括配置LDAP以及其他数据库的配置方法在文中也有说明,sdk方式的restful操作接口,可以查看fabric-ca源码根目录下的swagger.json文件。使用中需要根据区块链网络的特性,使用CA签发的数字证书进行认证、加密传输数据、授权用户、管理用户证书。