Fabric CA是Hyperledger Fabric的证书颁发机构

它提供了如下特征:

  •  注册身份,或以注册用户身份连接LDAP
  • 颁发登陆证书(ECerts)
  • 证书的更新和吊销

Fabric CA由客户端和服务端组成,稍后会详细介绍。

概述

下图说明了Fabric CA服务器如何适应Hyperledger Fabric架构

hyperledger fabric中的order和peer hyperledger fabric中文文档_配置文件

有两种方式和Fabric CA服务器交互。通过Fabric CA客户端或者通过Fabric SDK。所有和Fabric CA服务器通信都是通过REST API.查看fabric-ca/swagger/swagger-fabric-ca.json这些REST API的夸张文档。

Fabric CA client或者SDK可能连接的是一个Fabric CA服务器集群。可以从上图的右上角看出来。客户路由到HA Proxy终端,那里负责集群的负载均衡。

所有Fabric CA服务器集群共享一样的数据用于追踪身份和证书。如果配置了LDAP,身份信息会保存在LDAP而不是数据库中。

CA服务器可以包含多个CA,每个CA可能是根CA也可能是中间CA,每个中间证书都有一个父CA,它要么是根CA,要么是另一个中间CA。

开始

准备

  • 安装Go 1.10+
  • 设置GOPATH环境变量
  • 安装libtool  和 libtdhl-dev包

在Ubuntu上安装libtool依赖包

sudo apt install libtool libltdl-dev

在MacOSX上安装libtool

brew install libtool

注意:MacOSX上如果你使用Homebrew安装了libtool那么libtldl-dev就没必要安装了

关于libtool的更多信息,查看https://www.gnu.org/software/libtool

关于libltdl-dev的更多信息,查看https://www.gnu.org/software/libtool/manual/html_node/Using-libltdl.html

安装

接下来安装fabric-ca-server和fabric-ca-client可执行文件到$GOPATH/bin

go get -u github.com/hyperledger/fabric-ca/cmd/...

注意:如果你已经下载了fabric-ca库,在运行命令go get 之前确保你在主分支上,否则,你可能会看到如下错误:

<gopath>/src/github.com/hyperledger/fabric-ca; git pull --ff-only
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=<remote>/<branch> tlsdoc

package github.com/hyperledger/fabric-ca/cmd/fabric-ca-client: exit status 1

本地方式开启服务器

接下来以默认方式开启fabric-ca-server

fabric-ca-server start -b admin:adminpw

-b为引导管理员的ID和密码;如果没有设置LDAP中ldap.enabled,那么-b参数是必填的。

当前目录下会生成一个默认的配置文件fabric-ca-server-config.yaml

通过Docker启动Server

Docker Hub

地址:https://hub.docker.com/r/hyperledger/fabric-ca/tags/

找到合适的版本下载。

创建构建文件docker-compose.yml,修改下面参数

fabric-ca-server:
  image: hyperledger/fabric-ca:amd64-1.4.7
  container_name: fabric-ca-server
  ports:
    - "7054:7054"
  environment:
    - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
  volumes:
    - "./fabric-ca-server:/etc/hyperledger/fabric-ca-server"
  command: sh -c 'fabric-ca-server start -b admin:adminpw'

在含有上述文件的目录下执行如下命令

# docker-compose up -d

如果没有下载相应镜像会先下载fabric-ca镜像,然后实例化fabric-ca server

构建自己的docker镜像

你使用Docker Compose构建并开始server,命令如下

cd $GOPATH/src/github.com/hyperledger/fabric-ca
make docker
cd docker/server
docker-compose up -d

hyperledger/fabric-ca Docker镜像里即包含了fabric-ca-server也包含了fabric-ca-client

# cd $GOPATH/src/github.com/hyperledger/fabric-ca
# FABRIC_CA_DYNAMIC_LINK=true make docker
# cd docker/server
# docker-compose up -d

学习Fabric CA的终端命令

这部分内容展示了server和client的简单用法。其它用法请参考如下区域

下面的链接展示的是Server命令行Client命令行

注意:可以通过使用逗号分割的列表元素指定选项,或者通过多次指定选项来指定字符串片段(列表)的命令行选项,每个选项都有一个组成列表的字符串值。例如,为csr.hosts来指定host1和host2,你可以传递 --csr.hosts 'host1,host2'或者 --csr.hosts host1 --csr.hosts host2.如果你使用前一种格式,请保证逗号前后没有空格。

配置设置

有三种方式为server和client做设置。优先顺序是:

1.CLI参数

2.环境变量

3.配置文件

在下面的文档中,我们选用配置文件的方式。然而,配置文件的设定可以通过环境变量和CLI参数修改。

例如,如果client有如下配置文件

tls:
  # Enable TLS (default: false)
  enabled: false

  # TLS for the client's listenting port (default: false)
  certfiles:
  client:
    certfile: cert.pem
    keyfile:

环境变量可以重写文件中cert.pem的设置

export FABRIC_CA_CLIENT_TLS_CLIENT_CERTFILE=cert2.pem

如果你想要重写环境变量和配置文件。我们可以使用如下命令行

fabric-ca-client enroll --tls.client.certfile cert3.pem

fabric-ca-server也是同样道理

文件路径 

在配置文件中文件路径支持相对路径和绝对路径。相对路径是相对于配置文件所在目录的。例如如果配置目录是~/config,并且tls所在目录如下所示,server和client会在~/config目录中寻找 cert.pem,在~/config/certs目录中寻找key.pem文件,在/abs/path目录中

tls:
  enabled: true
  certfiles:
    - root.pem
  client:
    certfile: certs/cert.pem
    keyfile: /abs/path/key.pem

Fabric CA server

本部分来描述Fabric CA server。

在开始之前,首先需要初始化Fabric CA server。这里提供一个默认的配置文件。

server的主目录由一下决定:

  • 命令行中指定主目录
  • 还可以通过FABRIC_CA_SERVER_HOME 来设置
  • 还可以通过FABRIC_CA_HOME 来设置
  • 还可以通过CA_CFG_PATH 来设置
  • 或者使用当前的工作目录

本文接下来的内容,假定你设置了FABRIC_CA_HOME 是$HOME/fabric-ca/server

下面的文档假定配置文件就在server主目录中

初始化server

用下面命令初始化server

fabric-ca-server init -b admin:adminpw

当LDAP被禁用后使用-b(管理员用户)参数。启动server至少需要一个管理员;这个标识就是server的管理员。

服务器配置文件包含了Certificate Signing Request(CSR)部分,例如:

cn: fabric-ca-server
names:
   - C: US
     ST: "North Carolina"
     L:
     O: Hyperledger
     OU: Fabric
hosts:
  - host1.example.com
  - localhost
ca:
   expiry: 131400h
   pathlength: 1

上面的字段包含了X.509的签名秘钥和证书,这些是通过fabric-ca-server init.产生。对应于配置文件中的ca.certfile和ca.keyfile。说明如下

  • cn 是通用名
  • O 组织名称
  • OU是组织单位
  • L是地址或城市
  • ST 是州或省
  • C 国家

如果CSR需要自定义值,你可以自定义配置文件,删除ca.certfile和ca.keyfile项。然后再运行fabric-ca-server init -b admin:adminpw命令。

除非指定了-u <parent-fabric-ca-server-URL> 参数,fabric-ca-server init会产生一个自己签名的CA证书。如果-u指定了,那么证书会由父server签发。为了向父server验证身份,URL必须是<scheme>://<enrollmentID>:<secret>@<host>:<port>格式,其中<enrollmentID> 和 <secret>对应于hf.IntermediateCA中等于true的属性。fabric-ca-server init命令会在server的工作目录中生成fabric-ca-server-config.yaml的配置文件。

如果你想在server上使用自己提供的证书和key文件,就替代文件中的ca.certfile和ca.keyfile。每个文件都必须是PEM-encoded并且没有加密。CA证书必须以-----BEGIN CERTIFICATE-----开头,key文件必须以-----BEGIN PRIVATE KEY-----开头不能是----BEGIN ENCRYPTED PRIVATE KEY-----。

算法和秘钥大小

CSR可以自定义为X.509证书,keys必须支持椭圆曲线加密算法(ECDSA)。下面的设置是一个椭圆加密算法的例子,curve是prime256v1 ,签名算法是ecdsa-with-SHA256。

key:
   algo: ecdsa
   size: 256

算法和key大小是基于安全的需要而设定。

ECDSA提过了以下key的选项

size

ASN1 OID

Signature Algorithm

256

prime256v1

ecdsa-with-SHA256

384

secp384r1

ecdsa-with-SHA384

521

secp521r1

ecdsa-with-SHA512

开启服务

开启Fabric CA  server命令如下

fabric-ca-server start -b <admin>:<adminpw>

如果server还未被初始化,它第一次运行会自动初始化。在初始化过程中如果ca-cert.pem和ca-key.pem和配置文件不存在,系统会自动创建。参见初始化CA server部分。

除非使用LDAP,系统必须指定至少一个提前注册的起始账号来启动注册和登记其它账号。-b是用来指定这个起始账号的用户名和密码。

使server使用https而不是http,需要设置tls.enabled为true。

安全警告:Fabric CA server应该以TLS的方式启动(tls.enabled 为true)。如果不这样做,server很容易受到攻击。

限制注册时使用相同密码可以在配置文件中设置registry.maxenrollments。如果设置了1,那一个密码只能被一个用户使用。如果设置-1,则不限制密码的注册次数。默认值是-1。如果设置0,则server会禁止用户登陆和注册。

server现在占用7054端口监听。

如果你不想以集群方式运行server或者不想使用LDAP,你可以跳到Fabric CA Client文档部分。

配置数据库

这部分描述了server怎么配置数据库PostreSQL或者MySQL。默认数据库是SQLite,且默认的数据库文件是:fabric-ca-server.db,此文件在server的工作目录中。

如果你不关心server以集群方式运行,你可以跳过这部分;否则,你必须配置PostgreSQL或者MySQL。支持以下版本

  • PostgreSQL: 9.5.5 or later
  • MySQL: 5.7 or later

PostgreSQl(暂缺)

MySQL(暂缺)

配置LDAP(暂缺)

设置集群(暂缺)

设置多个CA

server默认设置一个默认CA,然而,其它CA可以增加到一个server上,使用cafiles或者cacount选项。每一个新增的CA需要有自己的工作目录

cacount:这个参数提供了一个快速的方法以X个数量的默认CA启动。工作目录关联到server的目录。有这个参数目录结果如下

--<Server Home>
  |--ca
    |--ca1
    |--ca2

每个额外的CA都会在各自的工作目录中产生一个默认的配置文件,其中包含了独自的CA名字。

#未翻译完,本章暂缺

注册中间CA

为了给中间CA创建一个签名证书,中间CA必须登录父CA,方法和client登陆CA相同。

#未翻译完,暂缺

升级server

server要在client升级之前升级。升级之前,建议数据库备份。

  • 如果使用sqlite3,备份当前数据文件。
  • 其它数据库,请使用各自适当的方法。

升级一个server实例:

1.停止server进程

2.确保当前数据库已经备份

3.用升级后的二进制执行文件替代之前的server可执行文件

4.启动server进程

5.验证进程是否正常启动

fabric-ca-client getcainfo -u http://<host>:7054

升级集群(暂缺)

操作服务

server有一个HTTP服务,提供了RESTful API,这些API是让操作员使用,而不是管理员或者普通用户。

API公开了以下功能:

Prometheus的操作目标

配置操作服务

操作服务需要两个基础配置:

监听的地址和端口。TLS证书和key用来验证和加密。注意,这些证书需要单独专门产生。不要使用通道中组织产生的证书。

CA 在配置文件的operations部分配置:

operations:
  # host and port for the operations server
  listenAddress: 127.0.0.1:9443

  # TLS configuration for the operations endpoint
  tls:
    # TLS enabled
    enabled: true

    # path to PEM encoded server certificate for the operations server
    cert:
      file: tls/server.crt

    # path to PEM encoded server key for the operations server
    key:
      file: tls/server.key

    # require client certificate authentication to access all resources
    clientAuthRequired: false

    # paths to PEM encoded ca certificates to trust for client authentication
    clientRootCAs:
      files: []

listenAddress 定义了监听的地址和端口,如果服务器要监听所有地址,则要省略host部分

tls部分用来表明TLS是否启用,证书和私钥的路径,可以被客户端信任的根证书的位置。当clientAuthRequired 为true,客户端需要有证书来做验证。

操作安全性

因为operations service重点是操作,且有意的和Fabric网络隔离,它没有采用MSP来做访问控制。相反的,操作服务完全依赖于具有客户端证书身份验证的相互TLS。

强烈建议在生产环境中通过将clientAuthRequired 设置为true,启用互相TLS。使用此配置,客户端需要提供有效的证书进行身份验证。如果客户端没有提供证书或者证书不能被校验通过,则请求会被拒绝。注意,如果clientAuthRequired 设置为false,客户端不需要提供证书;如果提供了,service对验证不通过,请求也会被拒绝。

当TLS被禁用,验证被跳过,则任意客户端可以链接到端口并操作API。

标准

Fabric CA公开了系统运行的指标。操作员和管理员可以通过这些信息来了解系统的运行。

配置标准

Fabric CA提供了两种公开指标的方法:基于Prometheus 的pull模型和基于StatsD的puh模型。

Prometheus

典型的Prometheus的部署通过检测目标公开的HTTP端点请求度量来获取度量。由于Prometheus负责请求度量,因此它被认为是一个pull系统。

当配置上了,Server会提供一个/metrics在操作的服务器上。启用Prometheus,请在server配置中设置:

metrics:
  provider: prometheus

StatsD

StatsD是一个简单的统计信息聚合守护进程。当收集了metrics后会发送给一个statsd进程,统计,推送到后端进行可视化和警报。由于此模型需要插入指令的进程将度量数据发送到StatsD,因此这被认为是一个推送系统。

通过在服务器的配置文件中的metrics部分将metrics提供程序设置为StatsD,可以将CA服务器配置为StatsD发送metrics。statsd子节点还必须配置statsd守护进程的地址,网络类型来使用(tcp或udp),还有发送metrics的频率。可选的prefix 项可以用来帮助区分metrics的资源,例如,不同的metrics来区分servers,所有生成的metrics都会预先添加。

metrics:
  provider: statsd
  statsd:
    network: udp
    address: 127.0.0.1:8125
    writeInterval: 10s
    prefix: server-0

查看生成的不同的metrics,Metrics Reference

Fabric CA Client

这部分用来描述怎样使用client命令。

client的家目录由以下几种方式指定:

  • 命令行选项 -home 指定
  • 设置环境变量FABRIC_CA_CLIENT_HOME 
  • 设置环境变量FABRIC_CA_HOME 
  • 设置环境变量CA_CFG_PATH 
  • 使用$HOME/.fabric-ca-client

下面假设在client家目录中存在client的配置文件。

注册引导身份

首先,如果需要定义CSR(Certificate Signing Request)部分在client的配置文件中。注意csr.cn文件必须设置引导身份的ID。默认的CSR值如下:

csr:
  cn: <<enrollment ID>>
  key:
    algo: ecdsa
    size: 256
  names:
    - C: US
      ST: North Carolina
      L:
      O: Hyperledger Fabric
      OU: Fabric CA
  hosts:
   - <<hostname of the fabric-ca-client>>
  ca:
    pathlen:
    pathlenzero:
    expiry:

查看 CSR fields来获取字段详情。

然后运行fabric-ca-client enroll命令来注册身份。例如,下面账号admin密码adminpw,server是本地的7054 端口。

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/admin
fabric-ca-client enroll -u http://admin:adminpw@localhost:7054

enroll命令存储注册证书(ECert),一致的私钥,和CA证书PEM文件在client的msp子目录中。你会看到标识PEM文件存储地址的信息。

注册新的账号

发送注册请求账号必须有注册相应账号的权限。

具体而言,CA server在注册期间会有三次权限检查:

1.注册人(即调用方)必须具有hf.Registrar.Roles属性和一个逗号分割的列表,列表中一个值等于正在注册的标识类型;例如,注册人hf.Registrar.Roles属性中有peer,注册人可以注册peer类型身份,但不可以注册client,admin,orderer。

2.登记员的从属关系必须等于或是所登记身份的从属关系的前缀。例如,隶属关系为“a.b”的注册官可以注册身份“a.b.c”,但不能注册隶属关系为“a.c”的身份。如果根隶属关系需要一个身份,那么隶属关系需要 “.” 且注册员必须有根隶属关系。如果在登记请求中没有指明隶属关系,则正在登记的身份将被赋予登记员的从属关系。

3.如果满足以下所有条件,则注册人可以使用属性注册身份:

  • 注册员可以注册前缀为“hf”的结构CA保留属性。仅当注册器拥有该属性并且它是hf.Registrar.Attributes的属性。此外,如果属性的类型是list,则要注册的属性的值必须等于注册器拥有的值或其子集。如果属性是boolean类型,则注册器只能在注册器的属性值为true时注册该属性。
  • 注册定义属性(即名称不以“hf”开头的任何属性)要求注册器具有 ‘hf.Registar.Attributes’ 属性,其中包含注册的属性和模式的值,唯一支持的模式是结尾带有'*'的字符串。例如, “a.b.*”意思是所有属性名称名字以“a.b.”开始。例如,如果注册人有hf.Registrar.Attributes=orgAdmin,那唯一的属性可以增删的属性是‘orgAdmin’。
  • 如果请求属性的名字是‘hf.Registrar.Attributes’,执行另一个检查,以查看此属性的请求的值是否等于或等于注册器的值的子集hf.Registrar.Attributes的属性。要使其为真,每个请求的值必须与注册器的值中的值匹配hf.Registrar.Attributes属性。例如,如果注册器的hf.Registrar.Attributes值为  'a.b.*,x.y.z'   ,请求的属性值是  'a.b.c,x.y.z'  ,它是有效的,因为'a.b.c'与'a.b.*'匹配,'x.y.z'与注册器的'x.y.z'值匹配。

例如:

      有效方案:

       1.如果注册人有属性hf.Registrar.Attributes = a.b.*, x.y.z  且注册属性a.b.c,那么a.b.c匹配为a.b.*

        2.如果注册人有属性hf.Registrar.Attributes = a.b.*, x.y.z  且注册属性x.y.z,验证通过,因为x.y.z匹配x.y.z。

        3.注册属性hf.Registrar.Attributes = a.b.*, x.y.z和请求属性值a.b.c, x.y.z,这样可验证因为a.b.c匹配了‘a.b.*’ and ‘x.y.z’ 匹配                了‘x.y.z’

         4.如果注册人有属性hf.Registrar.Roles = peer,client,admin,orderer,且请求属性是                                peer,‘peer,client,admin,orderer’, 或 ‘client,admin’可验证因为请求值等于或是注册人的值的子集。

          无效方案:

           1.如果注册人有属性hf.Registrar.Attributes = a.b.*, x.y.z且注册属性是hf.Registar.Attributes = a.b.c, x.y.*   ,验证不通过,因为请求属性x.y.*不是注册者的,x.y.*是x.y.z’的父集。

            2.如果注册人属性是hf.Registrar.Attributes = a.b.*, x.y.z且注册属性是hf.Registar.Attributes = a.b.c, x.y.z, attr1  ,验证不通过,因为注册人属性中不包含attr1

            3.如果注册人属性是hf.Registrar.Attributes = a.b.*, x.y.z且注册属性是a.b   ,验证不通过,因为a.b 不在a.b.*中。

            4.如果注册人属性是hf.Registrar.Attributes = a.b.*, x.y.z 且注册属性是x.y  ,验证不通过,因为x.y不包含x.y.z。

            5.如果注册人属性是hf.Registrar.Roles = peer  且请求值‘peer,client’  ,验证不通过,以为注册人的角色中不含有对应的角色。

            6. 如果注册属性是hf.Revoker = false   且请求值是true,验证不通过,因为hf.Revoker属性是一个布尔值且注册人的值不是true

下表列出了可以为标识注册的所有属性,属性名称区分大小写。

Name

Type

Description

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 an identity 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

注意:注册标识时,指定属性名称和值的数组。如果数组中包含了重名的元素,只有最后的元素会生效。换句话说,当前不支持多值属性。

下面的命令以admin的资质来创建一个新的身份标识admin2,从属于org1.department1,属性hf.Revoker值true,属性admin值true,:ecert后缀表示默认情况下,admin属性及其值将插入标识的注册证书中,然后可以使用该证书来做出访问控制决策。

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/admin
fabric-ca-client register --id.name admin2 --id.affiliation org1.department1 --id.attrs 'hf.Revoker=true,admin=true:ecert'

密码会打印出来,这个密码需要登入身份。这允许管理员来注册标识并可以让他们来登录。

使用–id.attrs 可以指定多个属性,每个属性必须是逗号分割。对于包含逗号的属性值,该属性必须用双引号封装。查看如下示例:

fabric-ca-client register -d --id.name admin2 --id.affiliation org1.department1 --id.attrs '"hf.Registrar.Roles=peer,client",hf.Revoker=true'

或者

fabric-ca-client register -d --id.name admin2 --id.affiliation org1.department1 --id.attrs '"hf.Registrar.Roles=peer,client"' --id.attrs hf.Revoker=true

可以在client的配置文件中修改命令的任意默认值。例如,支持配置文件包含如下内容:

id:
  name:
  type: client
  affiliation: org1.department1
  maxenrollments: -1
  attributes:
    - name: hf.Revoker
      value: true
    - name: anotherAttrName
      value: anotherAttrValue

下面的命令会注册一个新的身份标识admin3,使用命令行其余的参数在配置文件中,包含身份类型“client”,从属:“org1.department1”,和两个属性:hf.Revoker和anotherAttrName

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/admin
fabric-ca-client register --id.name admin3

要注册具有多个属性的标识,需要在配置文件中指定所有属性名称和值,如上所示。

将maxenrollments 设置为0或将其从配置中排除将导致注册标识使用CA的最大注册值。此外,正在注册的身份的最大注册值不能超过CA的最大注册值。例如,如果CA最大注册是5,任意新身份必须少于或等于5,并且不能设置为-1(无限注册)。

下面我们注册一个peer,用来在下一步中使用。下面的命令注册了peer1身份。注意我们选择自己指定密码而不是让服务器给我们生成密码。

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/admin
fabric-ca-client register --id.name peer1 --id.type peer --id.affiliation org1.department1 --id.secret peer1pw

请注意,从属关系区分大小写,但在服务器配置文件中指定的non-leaf从属关系除外,这里的存储总是以小写存储。例如,server配置文件中从属关系部分如下:

affiliations:
  BU1:
    Department1:
      - Team1
  BU2:
    - Department2
    - Department3

BU1, Department1, BU2以小写字母存储。这是因为Fabric CA使用Viper来读取配置。Viper将映射key视为不区分大小写,且始终返回小写值。注册身份使用Team1从属,bu1.department1.Team1需要使用–id.affiliation来指定:

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/admin
fabric-ca-client register --id.name client1 --id.type client --id.affiliation bu1.department1.Team1

注册peer

现在已经成功创建了peer的身份,你需要登录peer使用enrollment ID 和 secret。这个很像初始时登陆起始身份,除了需要使用-M指向Fabric的MSP目录。

下面命令登陆peer1.请确保-M指向你的peer的MSP目录,在core.yaml文件的mspConfigPath设置。也需要将FABRIC_CA_CLIENT_HOME 设置到peer的家目录。

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/peer1
fabric-ca-client enroll -u http://peer1:peer1pw@localhost:7054 -M $FABRIC_CA_CLIENT_HOME/msp

登陆orderer是一样的,除了指向的目录是orderer.yaml的LocalMSPDir。

fabric-ca server颁发的所有注册证书都具备如下组织单元(简称OU):

1.OU层次结构的根等于标识类型。

2.将为标识的从属关系的每个组件添加OU

例如,一个peer类型的身份标识从属于department1.team1,标识的OU层次(从leaf到root)是OU=team1, OU=department1, OU=peer.

获取身份混合器凭据

身份混合器(Idemix)是一个加密协议套件,用于隐私保护认证和认证属性的传输。Idemix允许客户端在没有发卡机构(CA)参与的情况下向验证器进行身份验证,并且仅选择性地公开验证器所需的那些属性,并且可以这样做而不必在其事务之间进行链接。

除了X509证书之外,Fabric CA server 可以颁发Idemix证书。可以通过将请求发送到/api/v1/Idemix/credential-api端点来请求一个Idemix凭证。更多信息和其它API请查阅 swagger-fabric-ca.json

Idemix 凭证发放需要分为两步。首先,发送一个空请求到/api/v1/idemix/credential来获取一个nonce和CA的Idemix 公钥。第二步,使用nonce和Idemix 公钥发送请求到/api/v1/idemix/credential来获取Idemix 证书,CRI,属性名和值。当前,只有三个属性支持:

  • OU 组织单元标识。此属性的值设置为标识的从属关系。例如,如果身份从属是dept1.unit1,OU属性设置为dept1.unit1
  • IsAdmin  身份是不是admin,此属性的值设置为isAdmin registration属性的值。
  • EnrollmentID 登录ID

可以参阅handleIdemixEnroll 函数在 https://github.com/hyperledger/fabric-ca/blob/master/lib/client.go 分两步过程来获取混合器凭据。

接口/api/v1/idemix/credential接收basic和token验证header。base验证header包含了账号和密码。如果身份标识已经包含了X509证书,这也可以用来创建token验证header。

注意Fabric支持客户端验证X509和混合器证书,但是peer和orderer只支持peer和orderer证书。像以前一样,应用可以使用Fabric SDK发送请求到Fabric CA server。SDK隐藏了创建授权头和请求的有效负载以及处理响应相关的复杂性。

获取Idemix CRI(Certificate Revocation Information证书吊销信息)

一个Idemix CRI很像X509的CRL(Certificate Revocation List):废除之前签发的。然而,有一些不同。

在X509,颁发者吊销终端用户的证书,其ID包含在CRL中。验证器检查用户的证书是否在CRL中,如果在,返回验证失败。除了从验证器接受授权错误外,终端用户不参与此吊销过程。

在Idmix,终端用户参与。发卡机构撤销一个与X509类似的最终用户凭证,该撤销的证据记录在CRI中。CRI给到终端用户(aka “prover”)。最终用户根据CRI生成一个证据,证明他们的凭证没有被吊销。最终用户将此证明交给验证者,验证者根据CRI验证证明。验证成功,用户使用的和验证机使用的CRI版本(称为epoch)必须一致。最新的CRI可以从/api/v1/idemix/cri获取。

当Fabric CA server接收到请求且吊销句柄池中没有剩余的吊销句柄时,CRI的版本将增加。这种情况下,fabric ca server必须生成一个新的句柄池,即增加CRI的epoch 。句柄池的数量是配置文件的idemix.rhpoolsize的属性。

续订证书

假设你的注册证书即将过期或已被泄露,您可以按如下方式发出reenroll命令以续订您的证书。

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/peer1
fabric-ca-client reenroll

撤销证书或身份

证书和身份可以被撤销。吊销证书会吊销证书拥有者身份的所有证书,并且阻止身份获取新的证书。吊销一个证书将使一个证书失效。

为了吊销一个身份证书,调用身份必须有hf.Revoker 和 hf.Registrar.Roles属性。吊销身份只能吊销一个证书或者具有与撤销标识的从属关系相同或前缀为该从属关系的标识。此外,撤销者只能在撤销者中列出的类型的标识hf.Registrar.Roles的属性。

例如,一个撤销者属于组织orgs.org1 且hf.Registrar.Roles=peer,client属性可以吊销peer或client身份属于 orgs.org1 或orgs.org1.department1但并不能吊销身份orgs.org2 或其它类型。以下命令禁用一个标识并撤销与该标识关联的所有证书。以后这个身份对Fabric server的请求将被拒绝。

fabric-ca-client revoke -e <enrollment_id> -r <reason>

-r可以使用以下reason:

  1. unspecified
  2. keycompromise
  3. cacompromise
  4. affiliationchange
  5. superseded
  6. cessationofoperation
  7. certificatehold
  8. removefromcrl
  9. privilegewithdrawn
  10. aacompromise

例如,起始admin(关联到根从属根)可以吊销peer1的身份:

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/admin
fabric-ca-client revoke -e peer1

所有属于身份的登录证书会被吊销通过指定它的AKI和序列数量:

fabric-ca-client revoke -a xxx -s yyy -r <reason>

例如,你可以获取AKI和证书的序列数量可以使用openssl 命令并将他们传入到revoke命令来吊销它们的证书:

serial=$(openssl x509 -in userecert.pem -serial -noout | cut -d "=" -f 2)
aki=$(openssl x509 -in userecert.pem -text | awk '/keyid/ {gsub(/ *keyid:|:/,"",$1);print tolower($0)}')
fabric-ca-client revoke -s $serial -a $aki -r affiliationchange

–gencrl可以用来生成一个CRL(证书废弃列表)。例如,如下命令会吊销peer1身份,生成CRL并储存在<msp folder>/crls/crl.pem

fabric-ca-client revoke -e peer1 --gencrl

CRL也可以使用gencrl 命令生成。查阅 Generating a CRL (Certificate Revocation List) 

生成一个CRL

Fabric CA server吊销一个证书后,Fabric的MSP必须升级。这包含了本地MSP的peer,以及适当通道配置中的块。为此,必须将PEM编码的CRL文件放在MSP的crls文件夹中。 fabric-ca-client gencrl命令也可以用来生成CRL。任何身份包含hf.GenCRL属性可以创建一个CRL,该CRL包含在某个使其内被吊销的所有证书的序列号。创建的CRL在<msp folder>/crls/crl.pem。

下面的命令创建一个CRL包含了所有吊销证书(过期和未过期),并存储CRL在~/msp/crls/crl.pem

export FABRIC_CA_CLIENT_HOME=~/clientconfig
fabric-ca-client gencrl -M ~/msp

下步命令创建CRL包含所有证书(过期与未过期),会在2017-09-13T16:39:57-08:00 之后吊销(使用–revokedafter指定),并且在2017-09-21T16:39:57-08:00之前(使用–revokedbefore指定)且CRL存储在~/msp/crls/crl.pem

export FABRIC_CA_CLIENT_HOME=~/clientconfig
fabric-ca-client gencrl --caname "" --revokedafter 2017-09-13T16:39:57-08:00 --revokedbefore 2017-09-21T16:39:57-08:00 -M ~/msp

启用TLS

这部分描述了如何为Fabric CA client 配置TLS。

如fabric-ca-client-config.yaml中

tls:
  # Enable TLS (default: false)
  enabled: true
  certfiles:
    - root.pem
  client:
    certfile: tls_client-cert.pem
    keyfile: tls_client-key.pem

certfiles 用于设置被客户端信任的根证书。这会是典型的Fabric CA server的根证书在家目录ca-cert.pem中。

当server端设置了client也需要设置TLS。

基于属性的访问控制

访问控制可以由链码决定,基于身份的属性。这被成为Attribute-Based Access Control,简称ABAC。

为了实现这个,一个身份登陆证书(ECert)包含一个或多个属性名字或值。然后,链码提取属性的值来做出访问控制决策。

例如,假设开发了一个应用app1且特定的链码操作只能由app1的管理员有权限。你的链码验证调用者的证书需要包含一个属性app1Admin值为true。当然属性名可以是任意的,值也不必非是布尔值。

怎样在登录证书中增加属性呢?有两种方法:

 1.注册标识时,可以指定为该标识颁发的注册证书在默认情况下应包含属性。可以在注册时重写,但这对于建立默认行为非常有用,并且假设注册发生在应用程序之外,则不需要对应用程序进行任何更改。

下面显示如何使用两个属性注册user1:app1Admin和email。”:ecert”后缀默认情况下会将appAdmin 属性插入到user1的注册证书中(当用户在注册时未显示请求属性时)。默认情况下,email属性不会添加进去。

fabric-ca-client register --id.name user1 --id.secret user1pw --id.type client --id.affiliation org1 --id.attrs 'app1Admin=true:ecert,email=user1@gmail.com'

2.当以一个身份登陆,你可以明确的将一个或多个属性添加到证书中。对于每个属性的请求,你可以指定属性是否可选。如果不是可选请求,并且标识不具有该属性,则会发生错误。

下面展示如何登陆user1时有email属性,没有 app1Admin属性,并且phone属性可选(如果用户拥有phone属性)。

fabric-ca-client enroll -u http://user1:user1pw@localhost:7054 --enrollment.attrs "email,phone:opt"

下表展示了每个标识注册的三种属性。

Attribute Name

Attribute Value

hf.EnrollmentID

The enrollment ID of the identity

hf.Type

The type of the identity

hf.Affiliation

The affiliation of the identity

要在默认情况下向证书添加上述任何属性,必须使用‘:ecert’规范明确注册该属性。例如,下面的注册标识user1这样hf.Affiliation属性会加到登记证书,如果在登记时没有请求特殊属性。注意值的从属关系(org1的)–id.affiliation ,–id.attrs 值必须一样。

fabric-ca-client register --id.name user1 --id.secret user1pw --id.type client --id.affiliation org1 --id.attrs 'hf.Affiliation=org1:ecert'

更多链码API的Attribute-Based Access Control,查看https://github.com/hyperledger/fabric-chaincode-go/blob/master/pkg/cid/README.md

动态修改server配置

这部分描述了怎样使用fabric-ca-client来动态修改fabric-ca-server配置部分,而不启动server。

本节中的所有命令都要求您首先通过执行fabric ca client enroll命令进行注册。

动态修改identities

如果客户端标识不满足以下所有条件,则会发生授权失败:

  • client身份必须是具有hf.Registrar.Roles具有逗号分割的值列表的属性,其中一个值等于正在更新的标识类型;例如,如果客户标识有hf.Registrar.Roles属性和值client,客户端可以修改该身份类型为client,但不能是peer。
  • 客户端的从属关系必须等于或是正在更新的身份的从属关系的前缀。例如,一个客户端的从属关系是“a.b”,可以更新的从属关系是“a.b.c”,但不能修改从属关系成”a.c“.如果根从属关系需要一个身份,那么修改请求需要为从属关系指定”.“,且客户端必须有根从属。

接下来展示怎样增加,修改该,删除从属关系。

获取身份信息

只要调用者满足上述部分强调的授权要求,调用者就可以从Fabric CA server检索身份信息。下面的命令展示了如何获取身份。

fabric-ca-client identity list --id user1

调用者还可以通过发出以下命令来请求检索其被授权查看的所有标识的信息。

fabric-ca-client identity list

增加身份

下面为user1增加一个新身份。增加新标识执行与通过”fabric ca client register“命令注册标识相同的操作。两种可行的方法来增加新身份。第一种方式是使用 –json

fabric-ca-client identity add user1 --json '{"secret": "user1pw", "type": "client", "affiliation": "org1", "max_enrollments": 1, "attrs": [{"name": "hf.Revoker", "value": "true"}]}'

下面使用根从属增加用户。注意”.“代表根从属

fabric-ca-client identity add user1 --json '{"secret": "user1pw", "type": "client", "affiliation": ".", "max_enrollments": 1, "attrs": [{"name": "hf.Revoker", "value": "true"}]}'

第二种方法直接使用flag指定

fabric-ca-client identity add user1 --secret user1pw --type client --affiliation . --maxenrollments 1 --attrs hf.Revoker=true

下面列出了标识的所有字段,必填或可选,默认值

Fields

Required

Default Value

ID

Yes

 

Secret

No

 

Affiliation

No

Caller’s Affiliation

Type

No

client

Maxenrollments

No

0

Attributes

No

 

修改身份

有两种可行方法来修改现有标识。第一种是通过–json来指定json字符串。在一个请求中可以进行多次修改。身份的没有修改的字段会保留之前的值。

注意:maxenrollments 设置为-2,要使用CA的最大注册设置。

下面的命令使用–json来对身份进行多个修改。

fabric-ca-client identity modify user1 --json '{"secret": "newPassword", "affiliation": ".", "attrs": [{"name": "hf.Regisrar.Roles", "value": "peer,client"},{"name": "hf.Revoker", "value": "true"}]}'

下面的命令直接使用flag进行修改,修改user1的密码

fabric-ca-client identity modify user1 --secret newsecret

下面将user1从属关系修改到org2

fabric-ca-client identity modify user1 --affiliation org2

下面将user1修改类型为peer

fabric-ca-client identity modify user1 --type peer

下面将user1的maxenrollments 修改该成5

fabric-ca-client identity modify user1 --maxenrollments 5

通过设置maxenrollments 为-2,将使user1使用CA的最大注册设置。

fabric-ca-client identity modify user1 --maxenrollments -2

下面将user1的hf.Revoker设置为false。如果身份有其它属性,它们不会更改。如果身份之前没有hf.Revoker属性,属性会增加到身份。也可以通过不为属性指定值来移除属性。

fabric-ca-client identity modify user1 --attrs hf.Revoker=false

下面删除user1的hf.Revoker属性

fabric-ca-client identity modify user1 --attrs hf.Revoker=

删除身份

以下操作将删除user1并删除相关联的证书

fabric-ca-client identity remove user1

注意:默认情况下CA server禁用删除身份,但可以通过server的–cfg.identities.allowremove来启用。

动态修改从属关系

 本部分介绍使用fabric ca client动态修改从属关系。下面展示怎样添加,修改,删除,列出从属关系。

增加从属关系

如果不满足下面条件验证会失败。

  • client的属性hf.AffiliationMgr设置为true。
  • client的从属关系必须要在更新的从属关系之上的层次结构上。例如,如果客户端的从属关系是"a.b",那客户端可以添加”a.b.c“但不能是”a.b“

下面添加新的从属关系org1.dept1

fabric-ca-client affiliation add org1.dept1

修改从属关系

需要满足以下条件

  • client的属性hf.AffiliationMgr设置为true。
  • client的从属关系必须要在更新的从属关系之上的层次结构上。例如,如果客户端的从属关系是"a.b",那客户端可以添加”a.b.c“但不能是”a.b“
  • 如果–force是true,且有身份必须修改,客户端必须获得授权修改身份。

下面重命名org2从属到org3。这也会重命名子从属关系(例如,org2.department1重命名为org3.department1)

fabric-ca-client affiliation modify org2 --name org3

如果某些附属机构的更名会影响某些身份,会抛出异常,除非使用了–force标签。使用了–force标签后,会修改附属关系的身份来使用新的名字。

fabric-ca-client affiliation modify org1 --name org2 --force

删除附属机构

客户端身份需要满足如下条件:

  • client的属性hf.AffiliationMgr设置为true。
  • client的从属关系必须要在更新的从属关系之上的层次结构上。例如,如果客户端的从属关系是"a.b",那客户端可以删除”a.b.c“但不能是”a.b“。
  • 如果–force为true,并且有身份要修改该,则还必须授权客户端标识来修改标识。

以下命令会删除org2从属关系及子从属关系。例如,如果org2.dept1从属于org2,那它也会删除。

fabric-ca-client affiliation remove org2

如果有受被删除从属关系的影响, 它会返回错误,除非–force选项被使用。使用–force来删除从属关系会删除关联的从属关系,还有关联的证书。

注意:fabric ca server默认情况下是禁用删除从属关系的,可以使用–cfg.affiliations.allowremove来启用选项。

列出从属关系信息

客户端身份必须满足如下条件:

  • 客户端身份的属性‘hf.AffiliationMgr必须为true。
  • 客户身份的从属关系必须等于或高于要更新的从属关系。例如,如果客户端的从属关系是“a.b”,客户端可以获取 “a.b” 或 “a.b.c”的信息,但不能获取 “a” 或 “a.c”.

下面命令展示了如何获取指定的信息。

fabric-ca-client affiliation list --affiliation org2.dept1

调用者还可以通过发出以下命令来请求检索其被授权查看的所有从属关系的信息。

fabric-ca-client affiliation list

管理证书

下面怎样使用fabric-ca-client来管理证书。

列出证书信息

调用方可见的证书包括:

  • 属于调用方的证书。
  • 如果调用者拥有hf.Registrar.Roles属性或者hf.Revoker 属性的值为true,所有属于调用方从属关系中及以下标识的证书。例如,如果客户端从属关系是a.b,客户端可以获取身份证书谁的从属关系是a.b 或 a.b.c 但不是 a 也不是 a.c

如何执行一个请求多个标识证书的list命令,只有从属关系等于或低于调用者从属关系的身份证书才会列出。

将列出的证书可以根据ID,AKI,序列号,过期实践,吊销时间,notrevoked和notexpired 标志进行筛选。

  • id:列出此注册ID的证书
  • serial:列出具有此序列号的证书
  • aki:列出有此AKI的证书
  • expiration:列出过期日期在此过期时间内的证书
  • revocation:列出在此吊销时间内被吊销的证书
  • notrevoked:列出还没有被废除的证书。
  • notexpired:列出还没有过期的证书。

可以使用notexpired和notrevoked作为筛选器,从结果集中排除吊销的证书或过期的证书。例如,如果只关系已过期但尚未吊销的证书,则可以使用expiration 和notrevoked 标志来获取类似的结果。下面提供了一个例子。

时间格式RFC3339。例如,列出在March 1, 2018 at 1:00 PM和June 15, 2018 at 2:00 AM之间过期的证书,输入的时间字符串是2018-03-01T13:00:00z 和2018-06-15T02:00:00z。如果时间不重要,只有日期,那么输入的字符串是2018-03-01和2018-06-15。

now可以代指当前时间,空字符串代指任意时间。例如,now:: 代指从现在到未来的任意时间,::now代指从过去到现在。

下面命令展示如何使用不同的筛选条件列出证书

所有证书:

fabric-ca-client certificate list

根据ID列出所有证书

fabric-ca-client certificate list --id admin

通过序列号和AKI列出证书:

fabric-ca-client certificate list --serial 1234 --aki 1234

列出证书通过 id 和 serial/aki

fabric-ca-client certificate list --id admin --serial 1234 --aki 1234

按ID列出既不是吊销也不是过期的证书

fabric-ca-client certificate list --id admin --notrevoked --notexpired

列出id(admin)尚未吊销的所有证书:

fabric-ca-client certificate list --id admin --notrevoked

列出id(admin)的所有尚未过期的证书:

“–notexpired”标志相当于“–expiration now::”,这意味着证书将在将来某个时间过期。

fabric-ca-client certificate list --id admin --notexpired

列出id(admin)的时间范围内吊销的所有证书:

fabric-ca-client certificate list --id admin --revocation 2018-01-01T01:30:00z::2018-01-30T05:00:00z

列出在一个时间范围内被吊销但id(admin)尚未过期的所有证书:

fabric-ca-client certificate list --id admin --revocation 2018-01-01::2018-01-30 --notexpired

使用id(admin)的持续时间(在30天和15天前吊销)列出所有吊销的证书:

fabric-ca-client certificate list --id admin --revocation -30d::-15d

在某个时间之前列出所有吊销的证书

fabric-ca-client certificate list --revocation ::2018-01-30

列出一段时间后所有吊销的证书

fabric-ca-client certificate list --revocation 2018-01-30::

列出现在之前和某个日期之后的所有被吊销的证书

fabric-ca-client certificate list --id admin --revocation 2018-01-30::now

列出在某个时间范围内过期但尚未吊销id(admin)的所有证书:

fabric-ca-client certificate list --id admin --expiration 2018-01-01::2018-01-30 --notrevoked

使用id(admin)的持续时间(在30天和15天前过期)列出所有过期的证书:

fabric-ca-client certificate list --expiration -30d::-15d

列出已过期或将在某个时间之前过期的所有证书

fabric-ca-client certificate list --expiration ::2058-01-30

列出所有已过期或将在一段时间后过期的证书

fabric-ca-client certificate list --expiration 2018-01-30::

列出当前和特定日期之后的所有过期证书

fabric-ca-client certificate list --expiration 2018-01-30::now

列出未来10天内到期的证书:

fabric-ca-client certificate list --id admin --expiration ::+10d --notrevoked

list certificate命令还可用于在文件系统上存储证书。这是在MSP中填充admins文件夹的一种方便方法,“-store”标志指向文件系统上存储证书的位置。

通过在MSP中存储标识的证书,将标识配置为管理员:

export FABRIC_CA_CLIENT_HOME=/tmp/clientHome
fabric-ca-client certificate list --id admin --store msp/admincerts

指定联系的CA实例

当服务器运行多个CA实例时,请求可以定向到特定的CA。默认情况下,如果在客户端请求中未指定CA名称,则请求将定向到fabric CA服务器上的默认CA。可以使用caname筛选器在客户端命令的命令行上指定CA名称,如下所示:

fabric-ca-client enroll -u http://admin:adminpw@localhost:7054 --caname <caname>

配置HSM

默认情况下,Fabric CA服务器和客户机将私钥存储在PEM编码的文件中,但也可以通过PKCS11 API将私钥存储在HSM(硬件安全模式)中。此行为在服务器或客户端配置文件的BCCSP(区块链加密服务提供商)部分配置。目前,Fabric只支持PKCS11标准与HSM通信。

例如

下面的示例演示如何配置Fabric CA服务器或客户机以使用名为SoftHSM的PKCS11软件版本(查阅 https://github.com/opendnssec/SoftHSMv2).

安装SoftHSM后,确保设置了环境变量SOFTHSM2_CONF 指向存放SoftHSM2 配置文件的目录,配置文件可能类似:

directories.tokendir = /tmp/
objectstore.backend = file
log.level = INFO

创建一个token,标记为ForFabric,设置pin为98765432(请参阅SoftHSM文档)。

你可以同时使用配置文件和环境变量来配置BCCSP。例如,设置server配置文件的bccsp部分如下,注意默认值是PKCS11

#############################################################################
# BCCSP (BlockChain Crypto Service Provider) section is used to select which
# crypto library implementation to use
#############################################################################
bccsp:
  default: PKCS11
  pkcs11:
    Library: /usr/local/Cellar/softhsm/2.1.0/lib/softhsm/libsofthsm2.so
    Pin: 98765432
    Label: ForFabric
    hash: SHA2
    security: 256
    filekeystore:
      # The directory used for the software file-based keystore
      keystore: msp/keystore

可以通过环境变量重写相关字段,如下所示:

FABRIC_CA_SERVER_BCCSP_DEFAULT=PKCS11
FABRIC_CA_SERVER_BCCSP_PKCS11_LIBRARY=/usr/local/Cellar/softhsm/2.1.0/lib/softhsm/libsofthsm2.so
FABRIC_CA_SERVER_BCCSP_PKCS11_PIN=98765432
FABRIC_CA_SERVER_BCCSP_PKCS11_LABEL=ForFabric

预构建的Hyperledger Fabric Docker映像未启用以便使用PKCS11。如果你以docker来部署Fabric CA,你需要建立你自己的

镜像并启用PKCS11,使用以下命令

make docker GO_TAGS=pkcs11

还需要通过安装PKCS11库或将其安装到容器中来确保CA可以使用PKCS11库。如果使用Docker Compose部署Fabric CA,则可以修改compose file,以使用卷将SoftHSM库和配置文件装入容器中。例如,增加下面的配置到docker的compose文件:

environment:
   - SOFTHSM2_CONF=/etc/hyperledger/fabric/config.file
volumes:
   - /home/softhsm/config.file:/etc/hyperledger/fabric/config.file
   - /usr/local/Cellar/softhsm/2.1.0/lib/softhsm/libsofthsm2.so:/etc/hyperledger/fabric/libsofthsm2.so

文件格式

Fabric CA server的文件格式

一个默认的配置文件在server的家目录中创建(查看 Fabric CA Server)。这里有个例子 Server configuration file

Fabric CA client的文件格式

一个默认的配置文件在client的家目录中创建(查看 Fabric CA Client),这里有个例子 Client configuration file

故障排除

1.如果看到Killed: 9错误,在OSX系统上,有一个详细的问题描述在https://github.com/golang/go/issues/19734。简而言之,要解决此问题,可以运行以下命令:

# sudo ln -s /usr/bin/true /usr/local/bin/dsymutil

2.如果发生以下序列时间会出现[ERROR] No certificates found for provided serial and aki

a.发出fabric ca client enroll命令,创建注册证书(即ECert)。这将在fabric ca服务器的数据库中存储ECert的副本。

b.fabric-ca-server的数据库被删除并重建,从而丢失步骤a中的Ecert。例如,如果停止并重新启动承载fabric ca服务器的Docker容器,但fabric ca服务器使用的是默认的sqlite数据库,并且数据库文件未存储在卷上,因此不是持久的,则可能会发生这种情况。

c.您可以从步骤“a”发出fabric ca client register命令或尝试使用ECert的任何其他命令。在这种情况下,由于数据库不再包含ECert,将出现[ERROR]no certificates found for provided serial and aki。

若要解决此错误,必须通过重复步骤“a”重新注册。这将发出一个新的ECert,它将存储在当前数据库中。

3.当向使用共享sqlite3数据库的Fabric CA服务器集群发送多个并行请求时,服务器偶尔会返回“database locked”错误。这很可能是因为数据库事务在等待释放数据库锁(由另一个集群成员持有)时超时。这是一个无效的配置,因为sqlite是一个嵌入式数据库,这意味着Fabric CA服务器群集必须通过共享文件系统共享同一个文件,这将引入SPoF(单点故障),这与群集拓扑的目的相矛盾.最佳实践是在集群拓扑中使用Postgres或MySQL数据库。

4.如果使用Fabric CA Server签发的证书时,由peer和orderer返回:Failed to deserialize creator identity, err The supplied identity is not valid, Verify() returned x509: certificate signed by unknown authority。这表示结构CA服务器用于颁发证书的签名CA证书与用于进行授权检查的MSP的cacerts或intermediatecerts文件夹中的证书不匹配。

用于进行授权检查的MSP取决于错误发生时执行的操作。例如,如果在peer上安装链码,则使用peer上的本地MSP;否则,如果你正在执行通道的某些操作,例如在通道上实例化链码,则使用genesis块的MSP或该通道的最新配置块中的MSP。要确认这是问题所在,请将注册证书的AKI(授权密钥标识符)与相应MSP的cacerts和intermediatecerts文件夹中证书的SKI(使用者密钥标识符)进行比较。命令openssl x509-in<PEM file>-noout-text | grep-A1“Authority Key Identifier”将显示AKI,openssl x509-in<PEM file>-noout-text | grep-A1“Subject Key Identifier”将显示SKI。如果它们不相等,则说明这是错误的原因。

这有很多中原因:

a.您使用cryptogen生成密钥材料,但没有使用cryptogen生成的签名密钥和证书启动fabric ca服务器。要解决(假设FABRIC_CA_SERVER_HOME设置为FABRIC CA服务器的主目录):

          a.停止fabric-ca-server

          b. 复制 crypto-config/peerOrganizations/<orgName>/ca/*pem 到 $FABRIC_CA_SERVER_HOME/ca-cert.pem.

          c.复制 crypto-config/peerOrganizations/<orgName>/ca/*_sk 到 $FABRIC_CA_SERVER_HOME/msp/keystore/.

          d.开启fabric-ca-server

          e.删除以前颁发的所有注册证书,并通过再次注册获取新证书。

b.在生成genesis块之后,删除并重新创建了Fabric CA服务器使用的CA签名密钥和证书。如果Fabric CA Server 在Docker中运行,容器已经重新启动,并且其主目录不在卷装载上,则可能发生这种情况。在这种情况下,Fabric CA服务器将创建一个新的CA签名秘钥和证书。

假设您无法恢复原始的CA签名密钥,从这种情况下恢复的唯一方法是将适当MSP的CAcert(或IntermediateRecerts)中的证书更新为新的CA证书。