1.简介

Fabric CA基于开源项目CFSSL开发, 主要为fabric网络提供PKI证书服务,是MSP生成的基础。 可能有人会问, 官方不是有cryptogen工具批量生成MSP吗? cryptogen实际是辅助测试工具,默认不同orderer,org都有不同的CA, 如果一个org要追加个peer或user, cryptogen就不管用了。生产环境我们建议使用fabric ca全面管理证书, 如果想简单来而区块链组织,节点和用户基本不会变, cryptogen也没问题。

2.架构

ca

我们在MSP已有类似提过。 https://www.javatree.cn/news/db31d44e278f40179116ad9f3a5618cc

Fabric CA默认部署为restful服务, 单点默认使用sqlite, 也可使用nginx, ha-proxy, keepalive实现高可用和均衡负载, 支持mysql等数据库持久化。

3.Fabric-CA启动

可以参考fabric-sample的basic-network例子启动ca。 有点要注意, 默认镜像是设置了账号为admin:adminpw.

docker inspect hyperledger/fabric-ca:1.4.0

会发现默认会执行Cmd fabric-ca-server start -b admin:adminpw

编写Docker-compose文件时command最好覆盖

command: sh -c 'fabric-ca-server start -b yourAccount:yourPassword'

貌似不大好, CA账户密码都暴露出来了。是否可以像传统数据库那样启动, 账号就保存在数据库里面。

默认sqlite是可以处理下, docker起个容器, 用清空配置, 使用fabric-ca-server init -b重新指定账号密码, 重新编辑生成的fabric-ca-server-config.yaml, 全部配置好使用新的这套配置启动fabric-ca即可。

使用mysql就还是得在fabric-ca-server-config.yaml配置数据库链接的账号密码, 绕不过。但是一个原则就是fabric-ca启动了, 务必不能让使用默认账号admin:adminpw, 就好像ssh暴露root账号一样危险。

4.Fabric-ca配置

实际上ca启动优先是命令行传入的参数, 其次是docker-compose环境变量, 再是fabric-ca-server-config.yaml配置, 参数较多, 我们就以yaml讲解具体配置, 里面也有不少注释,讲几个注意的点。

  • CA开启HTTPS需要配置enabled:true, 或者通过环境变量FABRIC_CA_TLS_ENABLED=true, 签名证书certfile,私钥keyfile, 可以使用互联网正式CA颁发的或自签名, 看使用场景。
tls:
  # Enable TLS (default: false)
  enabled: false
  # TLS for the server's listening port
  certfile:
  keyfile:
  clientauth:
    type: noclientcert
    certfiles:
  • 数据库默认是sqlite3, 也可以配置为mysql, datasource例如为 root:rootpw@tcp(localhost:3306)/fabric_ca?parseTime=true&tls=custom, 如果用mysql5.7要保证日期格式允许’0000-00-00’, 即my.cnf删除NO_ZERO_DATE。
db:
  type: sqlite3
  datasource: fabric-ca-server.db
  tls:
      enabled: false
      certfiles:
      client:
        certfile:
        keyfile:
  • Affiliations也是组织机构部门, CA register用户使用, 客户端可创建新的affiliation, affiliation笔者也有些疑惑,后面注册时说明。
affiliations:
   org1:
      - department1
      - department2
   org2:
      - department1
  • 签名有时效性,默认是1年半年, 按照实际需求适当的调整时间。
signing:
    default:
      usage:
        - digital signature
      expiry: 87600h
    profiles:
      ca:
         usage:
           - cert sign
           - crl sign
         expiry: 438000h
         caconstraint:
           isca: true
           maxpathlen: 0
      tls:
         usage:
            - signing
            - key encipherment
            - server auth
            - client auth
            - key agreement
         expiry: 87600h
  • CSR涉及到CA根证书的创建,可适当修改里面的名称, CA根证书默认15年有效。
csr:
   cn: fabric-ca-server
   keyrequest:
     algo: ecdsa
     size: 256
   names:
      - C: US
        ST: "North Carolina"
        L:
        O: Hyperledger
        OU: Fabric
   hosts:
     - 28e9b53aaa88
     - localhost
   ca:
      expiry: 131400h
      pathlength: 1

还有不少配置,参考官方文档 https://hyperledger-fabric-ca.readthedocs.io/en/release-1.1/users-guide.html 相对方便些应该还是把这些YAML配置项设置为对应的环境变量方便些。

5.注册用户

一些固定的用户我们可以使用fabric-ca-client生成。

默认的admin账号获取到证书

CA_ADMIN_ID="admin:adminpw"
fabric-ca-client enroll -H ca-admin-home -d   -u http://$CA_ADMIN_ID@localhost:7054

ca-admin-home结构如下, 主要是msp

[root@k8s-master ca-admin-home]# tree 
.
├── fabric-ca-client-config.yaml
└── msp
    ├── cacerts
    │   └── localhost-7054.pem
    ├── IssuerPublicKey
    ├── IssuerRevocationPublicKey
    ├── keystore
    │   └── 570aaaaadb9b185e68d6e6ae9c102bc2f04326b96f340568400e45a4fd9af71e_sk
    ├── signcerts
    │   └── cert.pem
└── user

假设创建orderer

CA_ADMIN_ID="admin@:adminpw"
ORDERER_NAME="orderer.example.com"
ORDERER_SECRET="123456"
fabric-ca-client register -H ca-admin-home  --id.name $ORDERER_NAME --id.secret $ORDERER_SECRET  --id.type orderer  -u  http://$CA_ADMIN_ID@localhost:7054
fabric-ca-client enroll  -H orderer-home --csr.names C=cn,ST=hubei,L=wuhan,O=example.com  -u http://$ORDERER_NAME:$ORDERER_SECRET@localhost:7054

生成目录, 里面是没tlsca的内容的, 可能需要额外再起创建账号生成一套。

[root@k8s-master orderer-home]# tree
.
├── fabric-ca-client-config.yaml
└── msp
    ├── cacerts
    │   └── localhost-7054.pem
    ├── IssuerPublicKey
    ├── IssuerRevocationPublicKey
    ├── keystore
    │   └── bb9de343d9bb7f92a02fa74b3be9e87fd8e3d6df78aa4cec17f0dcc6d2e2d259_sk
    ├── signcerts
    │   └── cert.pem
    └── user

时不时也要用openssl查看下证书内容, 尽量和cryptogen类似

openssl x509 -in cert.pem -noout -text

官方给出的很多例子, 都是通过O, OU等实际去确定角色, 例如first-network例子里org1的MSP里的config.yaml

NodeOUs:
  Enable: true
  ClientOUIdentifier:
    Certificate: cacerts/ca.org2.example.com-cert.pem
    OrganizationalUnitIdentifier: client
  PeerOUIdentifier:
    Certificate: cacerts/ca.org2.example.com-cert.pem
    OrganizationalUnitIdentifier: peer

而Java版fabric-ca-client SDK注册的时候可以传入affiliation, 命令行实际也可以设置, 但只是在生成证书的最后一段属性有生成, 可能hf.Type等就是默认直接对应到OU的角色, client, admin等, 但是cryptogen生成的内容是不包含这些attrs的,有点诡异,这些估计只能去跟源码了。

[root@k8s-master signcerts]# openssl x509 -in cert.pem -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            1a:65:3f:d1:27:60:fd:80:b8:50:c7:6a:36:0c:c9:6a:1e:e9:d0:83
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, ST=California, L=San Francisco, O=org1.example.com, CN=ca.org1.example.com
        Validity
            Not Before: Feb 19 11:36:00 2019 GMT
            Not After : Feb 19 11:41:00 2020 GMT
        Subject: C=cn, ST=hubei, L=wuhan, O=example.com, OU=orderer, CN=orderer.example.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub: 
                    04:0f:5f:d3:82:d1:41:7f:5a:30:1e:5c:33:85:23:
                    af:4c:56:20:ad:38:86:e6:cd:59:53:9f:61:e4:ac:
                    c8:1f:79:11:d2:c1:75:e6:7c:2d:94:d4:eb:73:e1:
                    7f:25:36:73:61:c2:03:7c:8e:01:42:bd:65:dd:25:
                    2f:ad:df:a1:e1
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier: 
                92:EF:D0:BB:EE:81:C0:4B:0F:F1:38:40:63:0D:A8:C7:53:D8:25:4C
            X509v3 Authority Key Identifier: 
                keyid:42:39:AA:0D:CD:76:DA:EE:B8:BA:0C:DA:70:18:51:D1:45:04:D3:1A:AD:1B:2D:DD:DB:AC:6A:57:36:5E:49:7C

            X509v3 Subject Alternative Name: 
                DNS:k8s-master
            1.2.3.4.5.6.7.8.1: 
                {"attrs":{"hf.Affiliation":"","hf.EnrollmentID":"orderer.example.com","hf.Type":"orderer"}}
    Signature Algorithm: ecdsa-with-SHA256
         30:44:02:20:5d:a5:09:bb:16:7e:89:0b:d7:00:f8:fc:17:fe:
         e3:7b:06:68:2b:0c:cf:d5:e6:5a:95:82:5b:cf:e7:06:7b:05:
         02:20:44:65:90:da:34:1e:e3:b1:b7:09:a7:64:27:d8:6b:6d:
         6c:e1:56:14:db:5d:68:aa:80:b4:3a:a0:2e:a6:f1:70

而java fabric-ca-client SDK用法我们在开源项目有相应代码, 也可以参考下用SDK注册用户 https://github.com/zealzeng/fabric-rest

6.小结

先来个入门,官方的文档实际还有不少内容不知道如何用在fabric的部署当中用到,1.3的id mixer还没用上,把东西做复杂不是自豪的事情,但有那么多大公司撑着fabric, 将就用着吧。