說明
Hyperledger Fabric CA是Hyperledger Fabric的證書授權中心,支持:
添加用戶、或者對接LDAP
簽發注冊證書
證書的更新和撤銷
概覽
如下圖所示,fabric-ca可以對接ldap,或者mysql、pgsql數據庫。
通過fabric-ca client或者fabric-ca的sdk獲得證書后,就可以用這些證書訪問Peer。
編譯安裝
$ go get -u github.com/hyperledger/fabric-ca $ cd $GOPATH/src/github.com/hyperledger/fabric-ca $ make fabric-ca-server $ make fabric-ca-client $ ls bin/ fabric-ca-client fabric-ca-server
fabric-ca-server初始化
mkdir -p /opt/app/fabric-ca/client cp $GOPATH/src/github.com/hyperledger/fabric-ca/bin/fabric-ca-client /opt/app/fabric-ca/client/ ln -s /opt/app/fabric-ca/client/fabric-ca-client /usr/bin/fabric-ca-client mkdir -p /opt/app/fabric-ca/server cp $GOPATH/src/github.com/hyperledger/fabric-ca/bin/fabric-ca-server /opt/app/fabric-ca/server/ cd /opt/app/fabric-ca/server
初始化,可以使用ldap、mysql、postgresql,或者本地sqlite,默認sqlite:
./fabric-ca-server init -b admin:pass
如果啟動的是中間CA,用-u
指定上級CA:
./fabric-ca-server start -b admin:adminpw -u http://<enrollmentID>:<secret>@<parentserver>:<parentport>
如果直接作為RootCA,后面兩個參數表示允許刪除聯盟和用戶:
./fabric-ca-server start -b admin:pass --cfg.affiliations.allowremove --cfg.identities.allowremove
初始化后,會在當前目錄生成以下文件:
ca-cert.pem fabric-ca-server-config.yaml fabric-ca-server.db msp/
fabric-ca-server-config.yaml是fabric-ca-server的配置文件。
其中ca-cert.pem
是一個自簽署的證書:
$ openssl verify -CAfile ca-cert.pem ca-cert.pem
ca-cert.pem: OK
這個證書是根據fabric-ca-server-config.yaml
中的csr
生成的:
csr: cn: fabric-ca-server names: - C: US ST: "North Carolina" L: O: Hyperledger OU: Fabric hosts: - 10-39-0-121 - localhost ca: expiry: 131400h pathlength: 1
可以用下面的命令查看:
openssl x509 -in ca-cert.pem -text
如果要生成被其它CA簽署的證書,使用-u
指定上一級CA:
-u <parent-fabric-ca-server-URL>
URL格式:
<scheme>://<enrollmentID>:<secret>@<host>:<port>
如果要簽署已經准備好的key,需要用ca.certfile
和ca.keyfile
指定:
ca: # Name of this CA name: # Key file (is only used to import a private key into BCCSP) keyfile: # Certificate file (default: ca-cert.pem) certfile: # Chain file chainfile:
msp/keystore
中存放的BCCSP (BlockChain Crypto Service Provider)
中用到的key:
bccsp: default: SW sw: hash: SHA2 security: 256 filekeystore: # The directory used for the software file-based keystore keystore: msp/keystore
還可以通過指定-cacount
生成多個CA:
fabric-ca-server start -b admin:adminpw --cacount 2
以及指定多個cafiles:
fabric-ca-server start -b admin:adminpw --cafiles ca/ca1/fabric-ca-config.yaml --cafiles ca/ca2/fabric-ca-config.yaml
每個cafiles格式如下:
ca: # Name of this CA name: <CANAME> csr: cn: <COMMONNAME>
目錄結構可以如下:
--<Server Home> |--ca |--ca1 |-- fabric-ca-config.yaml |--ca2 |-- fabric-ca-config.yaml
生成fabric-ca管理員的憑證
生成第一個用戶的憑證:
export FABRIC_CA_CLIENT_HOME=/opt/app/fabric-ca/clients/admin mkdir -p $FABRIC_CA_CLIENT_HOME fabric-ca-client enroll -u http://admin:pass@localhost:7054
或者:
fabric-ca-client enroll -u http://admin:pass@localhost:7054 -H `pwd`
在/opt/app/fabric-ca/clients/admin
可以看到生成了以下文件:
fabric-ca-client-config.yaml msp/
其中fabric-ca-client-config.yaml
是一個默認的配置文件,msp/
中存放的是相關的證書。
msp/ |-- cacerts | -- localhost-7054.pem |-- intermediatecerts | -- localhost-7054.pem |-- keystore | -- a17c01f53b037cbf51ad76f2a95684e6b2a4b8371e0b247949805af8035bf50e_sk -- signcerts -- cert.pem
之后就可以通過msp
目錄中的證書,訪問fabric-ca,不需要在輸入密碼。
查看聯盟成員
fabric-ca默認注冊了幾個聯盟,可以用affiliation list
查看:
$ fabric-ca-client affiliation list 2018/04/28 14:59:55 [INFO] 127.0.0.1:38094 GET /affiliations 200 0 "OK" affiliation: . affiliation: org1 affiliation: org1.department1 affiliation: org1.department2 affiliation: org2 affiliation: org2.department1
添加/刪除聯盟成員,也是通過這個命令進行:
fabric-ca-client affiliation add another
fabric-ca-client affiliation add another.sub
新增加的聯盟成員如下:
[root@10-39-0-121 admin]# fabric-ca-client affiliation list 2018/04/28 15:03:42 [INFO] 127.0.0.1:38104 GET /affiliations 201 0 "OK" affiliation: . affiliation: org1 affiliation: org1.department1 affiliation: org1.department2 affiliation: org2 affiliation: org2.department1 affiliation: another affiliation: another.sub1
默認是禁止刪除聯盟,如果需要開啟,需要在啟動fabric-ca-server時傳入參數--cfg.affiliations.allowremove
./fabric-ca-server start -b admin:pass --cfg.affiliations.allowremove
然后可以刪除:
fabric-ca-client affiliation remove another.sub1
如果聯盟下還有聯盟,可以加上參數-force
級聯刪除。
注冊新用戶
admin2
的用戶,先指定要使用的用戶的client目錄:
$ export FABRIC_CA_CLIENT_HOME=/opt/app/fabric-ca/clients/admin
也可以用-H
參數指定:
$ fabric-ca-client -H /opt/app/fabric-ca/clients/admin <其它參數...>
注冊新用戶的命令如下:
$ fabric-ca-client register --id.name admin2 --id.affiliation org1.department1 --id.attrs 'hf.Revoker=true,admin=true:ecert' 2018/04/28 10:20:42 [INFO] Configuration file location: /opt/app/fabric-ca/clients/admin/fabric-ca-client-config.yaml 2018/04/28 10:20:42 [INFO] 127.0.0.1:38036 POST /register 201 0 "OK" Password: wvkpvMzLsjPz
新用戶注冊后,會自動為新用戶生成一個密碼,新用戶需要使用這個密碼,生成自己的憑證,就像第一個用戶那樣。
為新注冊的用戶admin2
准備一個目錄,注意要使用一個新的目錄,防止與其它用戶混淆:
export FABRIC_CA_CLIENT_HOME=/opt/app/fabric-ca/clients/admin2
mkdir -p $FABRIC_CA_CLIENT_HOME
然后生成憑證:
fabric-ca-client enroll -u http://admin2:wvkpvMzLsjPz@localhost:7054
之后可以看到新的目錄中也生成了fabric-ca-client-config.yaml
和msp/
,這是admin2用戶的憑證:
$ tree admin2/ admin2/ |-- fabric-ca-client-config.yaml -- msp |-- cacerts | -- localhost-7054.pem |-- intermediatecerts | -- localhost-7054.pem |-- keystore | -- 6732d8d3802384c8935aa7174930975ba6141b6d4bc419e6ccbe5f4d76db58f0_sk -- signcerts -- cert.pem
用戶的屬性
在注冊admin2的時候,指定了這樣一些屬性--id.attrs 'hf.Revoker=true,admin=true:ecert'
:
fabric-ca-client register --id.name admin2 --id.affiliation org1.department1 --id.attrs 'hf.Revoker=true,admin=true:ecert'
這些屬性是一定要了解的,以hf.
開頭的屬性,是fabric-ca的內置屬性:
hf.Registrar.Roles List List of roles that the registrar is allowed to manage hf.Registrar.DelegateRoles List List of roles that the registrar is allowed to give to a registree for its ‘hf.Registrar.Roles’ attribute hf.Registrar.Attributes List List of attributes that registrar is allowed to register hf.GenCRL Boolean Identity is able to generate CRL if attribute value is true hf.Revoker Boolean Identity is able to revoke a user and/or certificates if attribute value is true hf.AffiliationMgr Boolean Identity is able to manage affiliations if attribute value is true hf.IntermediateCA Boolean Identity is able to enroll as an intermediate CA if attribute value is true
這些屬性表示的是用戶是否擁有相關的權限:
hf.Registrar.Roles
該用戶可以增加的新用戶類型,用戶類型都有:client、orderer、peer、user。
hf.Registrar.DelegateRoles
該用戶可以設置的新用戶的hf.Registrar.Roles
屬性。
hf.Registrar.Attributes
該用戶可以為新用戶設置的保留屬性和自定義屬性。
hf.GenCRL
該用戶是否可以獲取CRL列表,已經撤銷的證書列表。
hf.Revoker
該用戶是否能夠撤銷其它用戶。
hf.AffiliationMgr
該用戶是否可以管理聯盟。
hf.IntermediateCA
該用戶是否可以作為中間CA。
除了這些以hf.
開頭的屬性外,還可以自定義屬性,例如下面的admin=true
:
fabric-ca-client register --id.name admin2 --id.affiliation org1.department1 \ --id.attrs 'hf.Revoker=true,admin=true:ecert'
用戶自定義的屬性可以寫入到用戶的憑證中,在合約中可以獲取發起請求的用戶屬性,根據用戶屬性決定用戶是否由操作權限。
參考HyplerLedger FabricCA ABAC,HyperLedger Fabric Chaincode ABAC給出一個使用ABAC的chaincode:
... "github.com/hyperledger/fabric/core/chaincode/lib/cid" ... err := cid.AssertAttributeValue(stub, "abac.init", "true") if err != nil { return shim.Error(err.Error()) } ...
cid的使用說明見: HyperLedger Fabric: Client Identity Chaincode Library
cid(Client Identity)中提供下面的方法:
+AssertAttributeValue(stub ChaincodeStubInterface, attrName, attrValue string) : error +GetAttributeValue(stub ChaincodeStubInterface, attrName string) : string, bool, error +GetID(stub ChaincodeStubInterface) : string, error +GetMSPID(stub ChaincodeStubInterface) : string, error +GetX509Certificate(stub ChaincodeStubInterface) : *x509.Certificate, error +New(stub ChaincodeStubInterface) : ClientIdentity, error ▼+ClientIdentity : interface [methods] +AssertAttributeValue(attrName, attrValue string) : error +GetAttributeValue(attrName string) : string, bool, error +GetID() : string, error +GetMSPID() : string, error +GetX509Certificate() : *x509.Certificate, error
“admin=true:ecert”中的ecert
的意思是,該屬性會被自動寫入到用戶憑證中(enrollment certificate)。
對於沒有注明ecert
的屬性,可以在生成用戶憑證的時候,例如注冊了這樣一個用戶的時候:
fabric-ca-client register --id.name user1 --id.secret user1pw --id.type user \ --id.affiliation org1 --id.attrs 'app1Admin=true:ecert,email=user1@gmail.com'
它的屬性email=user1@gmail.com
沒有注明是ecert,在生成憑證的時候,可以指定下面的屬性:
fabric-ca-client enroll -u http://user1:user1pw@localhost:7054 --enrollment.attrs "email,phone:opt"
app1Admin
將被自動包含在憑證中;email
是被明確指定的,它必須是存在的,否則報錯;
phone:opt
也是明確指定的,opt
表示phone屬性可選的,如果沒有phone屬性不會報錯。
以hf.
開頭的下面三個屬性,也會被自動包含在登陸憑證中:
hf.EnrollmentID The enrollment ID of the identity
hf.Type The type of the identity
hf.Affiliation The affiliation of the identity
查看用戶詳情
可以用fabric-ca-client identity list
查看有權限
查看的用戶的詳情:
$ fabric-ca-client identity list Name: admin, Type: client, Affiliation: , Max Enrollments: -1, Attributes: [{Name:hf.GenCRL Value:1 ECert:false} {Name:hf.Registrar.Attributes Value:* ECert:false} {Name:hf.AffiliationMgr Value:1 ECert:false} {Name:hf.Registrar.Roles Value:peer,orderer,client,user ECert:false} {Name:hf.Registrar.DelegateRoles Value:peer,orderer,client,user ECert:false} {Name:hf.Revoker Value:1 ECert:false} {Name:hf.IntermediateCA Value:1 ECert:false}] Name: admin2, Type: client, Affiliation: org1.department1, Max Enrollments: -1, Attributes: [{Name:hf.Revoker Value:true ECert:false} {Name:admin Value:true ECert:true} {Name:hf.EnrollmentID Value:admin2 ECert:true} {Name:hf.Type Value:client ECert:true} {Name:hf.Affiliation Value:org1.department1 ECert:true}]
用戶的權利范圍
用戶的權利范圍是用聯盟屬性hf.Affiliation
來控制的。
hf.Affiliation The affiliation of the identity
聯盟屬性一個類似”a.b.c”樣式的字符串,最頂層用戶的該屬性為”.”。
一個用戶只能管理平級以及下級的用戶。
例如如果一個用戶的hf.Affiliation是”a.b.*“,那么它能管理的用戶的聯盟屬性必須以”a.b”開頭。
聯盟屬性可以配置多個,並且支持通配符,例如:
hf.Registrar.Attributes = a.b.*, x.y.z
另外:
一個用戶管理它的`hf.Registrar.Roles`屬性中列出用戶類型。
一個用戶能夠管理的其它用戶的屬性,只能是它的`hf.Registrar.Attributes`屬性列出的屬性。
其中保留屬性,還要求必須是當前用戶擁有的屬性。
后續的很多操作都受到權利范圍
的約束。