Hyperledger Fabric-ca调试

本文主要记录自己对Hyperledger fabric-ca的操作及认识,为原创内容,如有文中有书写或其他问题,请留言指导修正,互相交流,共同进步,本人QQ:417213902。

1、简单聊聊Fabric-ca模块

  • Fabric-ca模块其实是个证书颁发模块,仅有证书颁发功能,也就是说在做交易或者在链中做其他操作时,是不涉及ca模块,这里我最初不是这么认为的,我觉得应该是它颁发证书后,后面在链中每一次操作,ca模块都进行相应的配合验证校验功能,这对目前的fabric-ca模块是个误区。
  • 当然你也可以不用ca模块来管理证书,证书可以通过专门的证书部门生成根证书,然后在本地通过cryptogen工具自行生成证书(这个方式在上一篇文章中已经讲过)。
  • fabric-ca分为fabric-ca-client和fabric-ca-server,fabric-ca-server就是ca服务;fabric-ca-server是可以通过fabric-ca-client 来操作生成证书、登记、注册、撤销证书等操作。
  • 以下思路是通过作者自己不断的摸索得出的结论,不保证生产环境是否适用。

2、通过client端生成证书管理

2.1、前期准备

  • 修改docker-compose.yaml文件
    直接修改这个路径下的$GOPATH/src/github.com/hyperledger/fabric-sdk-java/src/test/fixture/sdkintegration/docker-compose.yaml文件
    直接贴脚本了,修改过的地方标注中文说明,主要是修改了两个ca的挂载目录,可以方便操作sqlite3数据库
#
# 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服务

此步骤会生成对应的文件

  • fabric-ca-server-config.yaml
    当前ca节点的相关配置
  • fabric-ca-server.db
    当前ca节点的sqlite的数据库
  • msp
    admin管理员的证书私钥
初始化ca服务,-n指定ca名称,-b指定启动的管理员用户名和密码,
#  fabric-ca-server init -n ca0  -b admin:adminpw
启动,start会检查 上述文件是否已经生成,若没有会重新生成
#  fabric-ca-server start -n ca0  -b admin:adminpw  -d
通过fabric-ca-server init会生成以下目录结构
.
|-- ca-cert.pem         CA证书文件,自签名 对这个文件做base64编码处理生成CAChain,如果再对生成后的CAChain做base64编码处理就会生成对应的CA证书内容,即ca-cert.pem文件
|-- fabric-ca-server-config.yaml    默认配置文件
|-- fabric-ca-server.db     存放数据的sqlite数据库
`-- msp
    `-- keystore    存放个人身份的私钥文件(_sk文件),对应签名证书
        `-- 3c163f464eef86178a729eb5b5c0d438c17de16f83f5db14b3cdf2ebe8260b6c_sk

后面的fabric-ca-client步骤统一放在docker方式里,因为操作是一样的

2.3、采用docker方式启动ca服务

按照上面的步骤替换或者修改docker-compose.yaml文件,完成后启动容器

#  cd $GOPATH/src/github.com/hyperledger/fabric-sdk-java/src/test/fixture/sdkintegration
   当然此处也可只启动ca容器
#  sh fabric.sh up
 可以看到两个文件夹fabric-ca-peerOrg1-server和fabric-ca-peerOrg2-server,他们分别是两个ca容器执行fabric-ca-server start后生成的文件,里面存放了admin用户的证书及当前ca的sqlite数据库
#  cd /etc/hyperledger
设置环境变量,客户端证书存放路径
#  export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/admin
登记管理员,将本地配置信息、生成的私钥和证书请求结构等发送到服务器,生成证书,然后会存储到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数据库中的数据
#  cd /etc/hyperledger/fabric-ca-peerOrg1-server
查看数据库
#  sqlite3 fabric-ca-server.db 
展示所有的表
#  .tables
这时可以看到有一条admin的数据
#  select * from users;
这里可以查询到admin的证书
#  select * from certificates;
执行fabric-ca-client enroll后生成的目录结构文件,首先利用本地配置信息(主要是csr字段下的信息)、生成的私钥和证书请求结构,构建EnrollmentRequestNet结构,之后通过Restful接口或enroll发送给服务端;服务器返回消息包括EnrollmentResponse结构信息,解析出相关的文件内容,并保存到本地。
.
|-- admin
|   |-- cacerts    存放服务器的证书
|   |   `-- localhost-7054.pem
|   |-- intermediatecerts     
|   |   `-- localhost-7054.pem
|   |-- keystore    客户端签名证书的私钥证书
|   |   `-- d5f8b9f98860a85d7970978526252ffcceaae23e2a7a1ce8c4c09a9496219a67_sk
|   `-- signcerts    服务端签发的代表客户端身份的证书
|       `-- cert.pem
`-- fabric-ca-client-config.yaml

sqlite3 表解读

  • users:当用户fabric-ca-clientregister或者管理员fabric-ca-server init时才会生成对应的用户注册数据
  • certificates:用户表对用的证书
  • affiliations:组织结构
  • properties:配置表
    下面我们再生成一个其他用户,以test为例
注册新用户前,必须先执行登记(可以理解为登录)管理员,才能执行新用户注册,name可以修改,此时会返回一个密码,用于后面登录
#  fabric-ca-client register --id.name name --id.type user --id.affiliation org1.department1 --id.attrs 'hf.Revoker=true,foo=bar'   
去数据库中查询users表和certificates表,结果是在users表中新增了一条test数据,而certificates表并没有新增数据,说明 fabric-ca-client register只是新增注册用户。
#  select * from users;
登记用户,并生成相应的证书,替换上面返回的密码
#  fabric-ca-client enroll -u http://name:TVCRFuAKIZvo@localhost:7054 -M $FABRIC_CA_CLIENT_HOME/msp
#  cd $FABRIC_CA_CLIENT_HOME/
可以看到新生成的证书
#  tree
去数据库中查询certificates表,发现生成一条新的证书
#  select * from certificates;

以上就是通过fabric-ca-client端生成证书的基本过程,注意在生产环境中因为可能会出现多个组织和多个用户,对个每个组织和用户都有其自己的证书,所以证书管理是个比较大的工作量,所以建议证书目录可以采用cryptogen generate 生成的crypto-config这个目录为准,还是比较清晰的。

这是一个用户的一套完整的证书
User1@org1.example.com
        |-- msp
        |   |-- admincerts      当前节点用户证书
        |   |   `-- User1@org1.example.com-cert.pem
        |   |-- cacerts         组织的根节点证书
        |   |   `-- ca.org1.example.com-cert.pem
        |   |-- keystore        当前节点用户的私钥
        |   |   `-- 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端生成证书管理

首先,先保证上一篇文章搭建能正常跑通,接下来的内容主要是根据官方提供的demo(即上一篇java版的demo),进行源码解读。

找到End2endIT这个类中的setup方法,主要是两个方法

  • enrollUsersSetup : 主要完成对ca的登记及证书的获取
  • runFabricTest : 链码、通道、peer节点初始化等操作

这里我们主要讲 enrollUsersSetup ,以下这几步在HFCAClient中的enroll方法中

(1) 生成一对keypair(公钥和私钥秘钥对)


image.png

(2) 用秘钥对中的公钥对用户名进行加密,生成一串密文


image.png

(3) 将密文发送登记(enroll)到ca服务端,返回证书链


image.png

(4) 对证书链做base64处理获得证书,此时的证书与服务器里certificates表中的证书一致


image.png

SampleOrg实体中有admin和peerOrgAdmin,比较容易混淆
admin:admin是client端的管理员,可以理解为组织中的超级管理员;
peerOrgAdmin:是节点管理员

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容