本文主要記錄自己對Hyperledger fabric-ca的操作及認(rèn)識,為原創(chuàng)內(nèi)容评姨,如有文中有書寫或其他問題甥雕,請留言指導(dǎo)修正踩身,互相交流,共同進步犀农,本人QQ:417213902惰赋。
1、簡單聊聊Fabric-ca模塊
- Fabric-ca模塊其實是個證書頒發(fā)模塊呵哨,僅有證書頒發(fā)功能赁濒,也就是說在做交易或者在鏈中做其他操作時,是不涉及ca模塊孟害,這里我最初不是這么認(rèn)為的拒炎,我覺得應(yīng)該是它頒發(fā)證書后,后面在鏈中每一次操作挨务,ca模塊都進行相應(yīng)的配合驗證校驗功能击你,這對目前的fabric-ca模塊是個誤區(qū)玉组。
- 當(dāng)然你也可以不用ca模塊來管理證書,證書可以通過專門的證書部門生成根證書丁侄,然后在本地通過cryptogen工具自行生成證書(這個方式在上一篇文章中已經(jīng)講過)惯雳。
- fabric-ca分為fabric-ca-client和fabric-ca-server,fabric-ca-server就是ca服務(wù);fabric-ca-server是可以通過fabric-ca-client 來操作生成證書鸿摇、登記石景、注冊、撤銷證書等操作拙吉。
- 以下思路是通過作者自己不斷的摸索得出的結(jié)論潮孽,不保證生產(chǎn)環(huán)境是否適用。
2筷黔、通過client端生成證書管理
2.1往史、前期準(zhǔn)備
- 修改docker-compose.yaml文件
直接修改這個路徑下的$GOPATH/src/github.com/hyperledger/fabric-sdk-java/src/test/fixture/sdkintegration/docker-compose.yaml文件
直接貼腳本了,修改過的地方標(biāo)注中文說明佛舱,主要是修改了兩個ca的掛載目錄椎例,可以方便操作sqlite3數(shù)據(jù)庫
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'
services:
ca0:
image: hyperledger/fabric-ca${IMAGE_TAG_FABRIC_CA}
environment:
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
ports:
- "7054:7054"
command: sh -c 'fabric-ca-server start -n ca0 ${V11_IDENTITIES_ALLOWREMOVE} ${V11_AFFILIATIONS_ALLOWREMOVE} --registry.maxenrollments -1 --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/e89b5807c72b15040d7ecdade99eb633995d2339e9b1faa672838a91278974ae_sk -b admin:adminpw ${ORG_HYPERLEDGER_FABRIC_SDKTEST_INTEGRATIONTESTS_CA_TLS} --tls.certfile /etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem --tls.keyfile /etc/hyperledger/fabric-ca-server-config/e89b5807c72b15040d7ecdade99eb633995d2339e9b1faa672838a91278974ae_sk -d'
volumes:
- ./e2e-2Orgs/${FAB_CONFIG_GEN_VERS}/crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config:ro
#為的是可以訪問fabric-ca-server中生成的文件
- /etc/hyperledger/fabric-ca-peerOrg1-server:/etc/hyperledger/fabric-ca-server
container_name: ca_peerOrg1
ca1:
image: hyperledger/fabric-ca${IMAGE_TAG_FABRIC_CA}
environment:
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
ports:
- "8054:7054"
command: sh -c 'fabric-ca-server start --registry.maxenrollments -1 --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org2.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/7ba11256a588037957071ad894de23902bd42908b1b183bb03387ae09c133b44_sk -b admin:adminpw ${ORG_HYPERLEDGER_FABRIC_SDKTEST_INTEGRATIONTESTS_CA_TLS} --tls.certfile /etc/hyperledger/fabric-ca-server-config/ca.org2.example.com-cert.pem --tls.keyfile /etc/hyperledger/fabric-ca-server-config/7ba11256a588037957071ad894de23902bd42908b1b183bb03387ae09c133b44_sk -d'
volumes:
- ./e2e-2Orgs/${FAB_CONFIG_GEN_VERS}/crypto-config/peerOrganizations/org2.example.com/ca/:/etc/hyperledger/fabric-ca-server-config:ro
#為的是可以訪問fabric-ca-server中生成的文件
- /etc/hyperledger/fabric-ca-peerOrg2-server:/etc/hyperledger/fabric-ca-server
container_name: ca_peerOrg2
orderer.example.com:
container_name: orderer.example.com
image: hyperledger/fabric-orderer${IMAGE_TAG_FABRIC}
environment:
- ORDERER_GENERAL_LOGLEVEL=debug
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/etc/hyperledger/configtx/orderer.block
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
- ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/msp/orderer/msp
- ORDERER_GENERAL_TLS_ENABLED=${ORG_HYPERLEDGER_FABRIC_SDKTEST_INTEGRATIONTESTS_TLS}
- ORDERER_GENERAL_TLS_PRIVATEKEY=/etc/hyperledger/msp/orderer/tls/server.key
- ORDERER_GENERAL_TLS_CERTIFICATE=/etc/hyperledger/msp/orderer/tls/server.crt
- ORDERER_GENERAL_TLS_ROOTCAS=[/etc/hyperledger/msp/orderer/tls/ca.crt]
- GRPC_TRACE=all=true,
- GRPC_VERBOSITY=debug
- ORDERER_GENERAL_AUTHENTICATION_TIMEWINDOW=3600s #Not for production -- remove.
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: orderer
volumes:
- ./e2e-2Orgs/${FAB_CONFIG_GEN_VERS}:/etc/hyperledger/configtx:ro
- ./e2e-2Orgs/${FAB_CONFIG_GEN_VERS}/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/:/etc/hyperledger/msp/orderer:ro
ports:
- 7050:7050
peer0.org1.example.com:
container_name: peer0.org1.example.com
extends:
file: peer-base/peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer0.org1.example.com
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
# - CORE_PEER_GOSSIP_ORGLEADER=true
- CORE_PEER_LOCALMSPID=Org1MSP
volumes:
- /var/run/:/host/var/run/
- ./e2e-2Orgs/${FAB_CONFIG_GEN_VERS}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/:/etc/hyperledger/msp/peer:ro
ports:
- 7051:7051
- 7053:7053
depends_on:
- orderer.example.com
peer1.org1.example.com:
container_name: peer1.org1.example.com
extends:
file: peer-base/peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer1.org1.example.com
- CORE_PEER_ADDRESS=peer1.org1.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.example.com:7051
# - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
volumes:
- /var/run/:/host/var/run/
- ./e2e-2Orgs/${FAB_CONFIG_GEN_VERS}/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/:/etc/hyperledger/msp/peer:ro
ports:
- 7056:7051
- 7058:7053
depends_on:
- orderer.example.com
- peer0.org1.example.com
peer0.org2.example.com:
container_name: peer0.org2.example.com
extends:
file: peer-base/peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer0.org2.example.com
- CORE_PEER_ADDRESS=peer0.org2.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:8051
# - CORE_PEER_GOSSIP_ORGLEADER=true
- CORE_PEER_LOCALMSPID=Org2MSP
volumes:
- /var/run/:/host/var/run/
- ./e2e-2Orgs/${FAB_CONFIG_GEN_VERS}/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/:/etc/hyperledger/msp/peer:ro
ports:
- 8051:7051
- 8053:7053
depends_on:
- orderer.example.com
peer1.org2.example.com:
container_name: peer1.org2.example.com
extends:
file: peer-base/peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer1.org2.example.com
- CORE_PEER_ADDRESS=peer1.org2.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org2.example.com:8051
# - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:8051
- CORE_PEER_LOCALMSPID=Org2MSP
volumes:
- /var/run/:/host/var/run/
- ./e2e-2Orgs/${FAB_CONFIG_GEN_VERS}/crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/:/etc/hyperledger/msp/peer:ro
ports:
- 8056:7051
- 8058:7053
depends_on:
- orderer.example.com
- peer0.org2.example.com
configtxlator:
image: hyperledger/fabric-tools${IMAGE_TAG_FABRIC}
ports:
- "7059:7059"
command: /usr/local/bin/configtxlator start
container_name: configtxlator
ccenv:
image: hyperledger/fabric-ccenv${IMAGE_TAG_FABRIC}
- 后面的所有操作是保證按照上一篇文章操作過來的。
2.2名眉、采用非docker方式啟動ca服務(wù)
此步驟會生成對應(yīng)的文件
- fabric-ca-server-config.yaml
當(dāng)前ca節(jié)點的相關(guān)配置 - fabric-ca-server.db
當(dāng)前ca節(jié)點的sqlite的數(shù)據(jù)庫 - msp
admin管理員的證書私鑰
初始化ca服務(wù)粟矿,-n指定ca名稱,-b指定啟動的管理員用戶名和密碼损拢,
# fabric-ca-server init -n ca0 -b admin:adminpw
啟動,start會檢查 上述文件是否已經(jīng)生成撒犀,若沒有會重新生成
# fabric-ca-server start -n ca0 -b admin:adminpw -d
通過fabric-ca-server init會生成以下目錄結(jié)構(gòu)
.
|-- ca-cert.pem CA證書文件福压,自簽名 對這個文件做base64編碼處理生成CAChain,如果再對生成后的CAChain做base64編碼處理就會生成對應(yīng)的CA證書內(nèi)容或舞,即ca-cert.pem文件
|-- fabric-ca-server-config.yaml 默認(rèn)配置文件
|-- fabric-ca-server.db 存放數(shù)據(jù)的sqlite數(shù)據(jù)庫
`-- msp
`-- keystore 存放個人身份的私鑰文件(_sk文件)荆姆,對應(yīng)簽名證書
`-- 3c163f464eef86178a729eb5b5c0d438c17de16f83f5db14b3cdf2ebe8260b6c_sk
后面的fabric-ca-client步驟統(tǒng)一放在docker方式里,因為操作是一樣的
2.3映凳、采用docker方式啟動ca服務(wù)
按照上面的步驟替換或者修改docker-compose.yaml文件胆筒,完成后啟動容器
# cd $GOPATH/src/github.com/hyperledger/fabric-sdk-java/src/test/fixture/sdkintegration
當(dāng)然此處也可只啟動ca容器
# sh fabric.sh up
可以看到兩個文件夾fabric-ca-peerOrg1-server和fabric-ca-peerOrg2-server,他們分別是兩個ca容器執(zhí)行fabric-ca-server start后生成的文件诈豌,里面存放了admin用戶的證書及當(dāng)前ca的sqlite數(shù)據(jù)庫
# cd /etc/hyperledger
設(shè)置環(huán)境變量仆救,客戶端證書存放路徑
# export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/admin
登記管理員,將本地配置信息矫渔、生成的私鑰和證書請求結(jié)構(gòu)等發(fā)送到服務(wù)器彤蔽,生成證書,然后會存儲到fabric-ca-server.db中庙洼,并返回到client端顿痪,在本地以文件形式保存下來
# fabric-ca-client enroll -u http://admin:adminpw@localhost:7054
# cd $FABRIC_CA_CLIENT_HOME
可以看到在客戶端生成的證書镊辕,tree命令自行安裝 yum install tree
# tree
接著我們看下sqlite3數(shù)據(jù)庫中的數(shù)據(jù)
# cd /etc/hyperledger/fabric-ca-peerOrg1-server
查看數(shù)據(jù)庫
# sqlite3 fabric-ca-server.db
展示所有的表
# .tables
這時可以看到有一條admin的數(shù)據(jù)
# select * from users;
這里可以查詢到admin的證書
# select * from certificates;
執(zhí)行fabric-ca-client enroll后生成的目錄結(jié)構(gòu)文件,首先利用本地配置信息(主要是csr字段下的信息)蚁袭、生成的私鑰和證書請求結(jié)構(gòu)征懈,構(gòu)建EnrollmentRequestNet結(jié)構(gòu),之后通過Restful接口或enroll發(fā)送給服務(wù)端揩悄;服務(wù)器返回消息包括EnrollmentResponse結(jié)構(gòu)信息卖哎,解析出相關(guān)的文件內(nèi)容,并保存到本地虏束。
.
|-- admin
| |-- cacerts 存放服務(wù)器的證書
| | `-- localhost-7054.pem
| |-- intermediatecerts
| | `-- localhost-7054.pem
| |-- keystore 客戶端簽名證書的私鑰證書
| | `-- d5f8b9f98860a85d7970978526252ffcceaae23e2a7a1ce8c4c09a9496219a67_sk
| `-- signcerts 服務(wù)端簽發(fā)的代表客戶端身份的證書
| `-- cert.pem
`-- fabric-ca-client-config.yaml
sqlite3 表解讀
- users:當(dāng)用戶fabric-ca-clientregister或者管理員fabric-ca-server init時才會生成對應(yīng)的用戶注冊數(shù)據(jù)
- certificates:用戶表對用的證書
- affiliations:組織結(jié)構(gòu)
- properties:配置表
下面我們再生成一個其他用戶棉饶,以test為例
注冊新用戶前,必須先執(zhí)行登記(可以理解為登錄)管理員镇匀,才能執(zhí)行新用戶注冊照藻,name可以修改,此時會返回一個密碼汗侵,用于后面登錄
# fabric-ca-client register --id.name name --id.type user --id.affiliation org1.department1 --id.attrs 'hf.Revoker=true,foo=bar'
去數(shù)據(jù)庫中查詢users表和certificates表幸缕,結(jié)果是在users表中新增了一條test數(shù)據(jù),而certificates表并沒有新增數(shù)據(jù)晰韵,說明 fabric-ca-client register只是新增注冊用戶发乔。
# select * from users;
登記用戶,并生成相應(yīng)的證書,替換上面返回的密碼
# fabric-ca-client enroll -u http://name:TVCRFuAKIZvo@localhost:7054 -M $FABRIC_CA_CLIENT_HOME/msp
# cd $FABRIC_CA_CLIENT_HOME/
可以看到新生成的證書
# tree
去數(shù)據(jù)庫中查詢certificates表雪猪,發(fā)現(xiàn)生成一條新的證書
# select * from certificates;
以上就是通過fabric-ca-client端生成證書的基本過程栏尚,注意在生產(chǎn)環(huán)境中因為可能會出現(xiàn)多個組織和多個用戶,對個每個組織和用戶都有其自己的證書只恨,所以證書管理是個比較大的工作量译仗,所以建議證書目錄可以采用cryptogen generate 生成的crypto-config這個目錄為準(zhǔn),還是比較清晰的官觅。
這是一個用戶的一套完整的證書
User1@org1.example.com
|-- msp
| |-- admincerts 當(dāng)前節(jié)點用戶證書
| | `-- User1@org1.example.com-cert.pem
| |-- cacerts 組織的根節(jié)點證書
| | `-- ca.org1.example.com-cert.pem
| |-- keystore 當(dāng)前節(jié)點用戶的私鑰
| | `-- 6f6a67f77af274c92a615521923b8d833105f2a1906870b6ce2acfe4ed06e15b_sk
| |-- signcerts
| | `-- User1@org1.example.com-cert.pem
| `-- tlscacerts
| `-- tlsca.org1.example.com-cert.pem
`-- tls
|-- ca.crt
|-- client.crt
`-- client.key
3纵菌、通過Java-sdk端生成證書管理
首先,先保證上一篇文章搭建能正常跑通休涤,接下來的內(nèi)容主要是根據(jù)官方提供的demo(即上一篇java版的demo)咱圆,進行源碼解讀。
找到End2endIT這個類中的setup方法功氨,主要是兩個方法
- enrollUsersSetup : 主要完成對ca的登記及證書的獲取
- runFabricTest : 鏈碼序苏、通道、peer節(jié)點初始化等操作
這里我們主要講 enrollUsersSetup 疑故,以下這幾步在HFCAClient中的enroll方法中
(1) 生成一對keypair(公鑰和私鑰秘鑰對)
(2) 用秘鑰對中的公鑰對用戶名進行加密杠览,生成一串密文
(3) 將密文發(fā)送登記(enroll)到ca服務(wù)端,返回證書鏈
(4) 對證書鏈做base64處理獲得證書纵势,此時的證書與服務(wù)器里certificates表中的證書一致
SampleOrg實體中有admin和peerOrgAdmin,比較容易混淆
admin:admin是client端的管理員踱阿,可以理解為組織中的超級管理員;
peerOrgAdmin:是節(jié)點管理員