在上一篇文章中,我们初步搭建并运行Fabric Samples 里面的BYFN, 在这篇文章中我们开始逐步分析这里面的一些知识, 包括PKI基础知识、cryptogen、configtxgen 等基本用法, 以及orderer的创始区块等。
generate 到底生成了什么?
我们最开始运行的是-m generate, 运行结果如下, 那我们到底generate 了哪些东西呢?
先来整体看一下:
下面我们来逐一分析。
generateCerts
这个task要执行的命令是很简单的一行:
主要是调用cryptogen generate的功能, 通过解析crypto-config.yaml这个配置文件, 来产生区块链网络运行所需要的密码材料(X.509 证书等)。 这些证书是基于标准的PKI 实现的, 验证工作是通过抵达一个公共的可信任锚点达到的。
复习一下PKI的基本知识:
公开密钥基础建设(英语:Public Key Infrastruction, 缩写:PKI), 又称公开密钥基础架构、公钥基础建设等, 是一组由硬件、软件、参与者、管理政策与流程组成的基础结构, 其目的在于创造、管理、分配、使用、存储以及撤销数字证书。
一个典型的PKI系统如图1所示,其中包括PKI策略、软硬件系统、证书机构CA、注册机构RA、证书发布系统和PKI应用等。
1. PKI安全策略建立和定义了一个组织信息安全方面的指导方针,同时也定义了密码系统使用的处理方法和原则。它包括一个组织怎样处理密钥和有价值的信息,根据风险的级别定义安全控制的级别。
2. 证书机构CA是PKI的信任基础,它管理公钥的整个生命周期,其作用包括:发放证书、规定证书的有效期和通过发布证书废除列表(CRL)确保必要时可以废除证书。
CA 机构,又称为证书认证中心 (Certificate Authority) 中心,是一个负责发放和管理数字证书的第三方权威机构,它负责管理PKI结构下的所有用户(包括各种应用程序)的证书。CA机构的数字签名使得攻击者不能伪造和篡改证书。
认证中心主要有以下5个功能:
证书的颁发:接收、验证用户(包括下级认证中心和最终用户)的数字证书的申请。可以受理或拒绝
证书的更新:认证中心可以定期更新所有用户的证书,或者根据用户的请求来更新用户的证书
证书的查询:查询当前用户证书申请处理过程;查询用户证书的颁发信息,这类查询由目录服务器ldap来完成
证书的作废:由于用户私钥泄密等原因,需要向认证中心提出证书作废的请求;证书已经过了有效期,认证中心自动将该证书作废。认证中心通过维护证书作废列表 (Certificate Revocation List,CRL) 来完成上述功能。
证书的归档:证书具有一定的有效期,证书过了有效期之后就将作废,但是我们不能将作废的证书简单地丢弃,因为有时我们可能需要验证以前的某个交易过程中产生的数字签名,这时我们就需要查询作废的证书。
3. 注册机构RA提供用户和CA之间的一个接口,它获取并认证用户的身份,向CA提出证书请求。它主要完成收集用户信息和确认用户身份的功能。
密码学上, 公开密钥基础建设借着数字证书认证机构(CA)将用户的个人身份和公开密钥链接在一起。对每个证书中心用户的身份必须是唯一的。链接关系通过注册和发布过程创建, 取决于担保级别,链接关系可能由CA的各种软件或者在人为监督下完成。PKI确定链接关系的这一角色称为注册管理中心(Registration Autority, RA)。 RA确保公开密钥和个人身份链接, 可以防止抵赖。
4. 证书发布系统负责证书的发放,如可以通过用户自己,或是通过目录服务。目录服务器可以是一个组织中现存的,也可以是PKI方案中提供的。
一个简单的PKI系统包括证书机构CA、注册机构RA和相应的PKI存储库。CA用于签发并管理证书;RA可作为CA的一部分,也可以独立,其功能包括个人身份审核、CRL管理、密钥产生和密钥对备份等;PKI存储库包括LDAP目录服务器和普通数据库,用于对用户申请、证书、密钥、CRL和日志等信息进行存储和管理,并提供一定的查询功能。
PKI 中最基本的元素就是数字证书(Certificate)。所有安全的操作主要通过证书来实现。数字证书是一种数字标识,可以说是Internet上的安全护照或身份证明。当人们到其他国家旅行时,用户护照可以证实其身份,并被获准进入这个国家。数字证书提供的是网络上的身份证明。
数字证书是一个经证书授权中心数字签名的包含公开密钥拥有者信息和公开密钥的文件。最简单的证书包含一个公开密钥、名称以及证书授权中心的数字签名。一般情况下证书中还包括密钥的有效时间,发证机关(证书授权中心)的名称,该证书的序列号等信息,证书的格式遵循ITUT X.509国际标准。
在Internet网络中,应用程序使用的证书都来自不同的厂商或组织,为了实现可交互性,要求证书能够被不同的系统识别,符合一定的格式,并实现标准化。X.509为证书及其CRL格式提供了一个标准。但X.509本身不是Internet标准,而是国际电联ITU标准,它定义了一个开放的框架,并在一定的范围内可以进行扩展。
证书机构CA用于创建和发布证书,它通常为一个称为安全域(security domain)的有限群体发放证书。创建证书的时候,CA系统首先获取用户的请求信息,其中包括用户公钥(如果用户端是个人使用或者测试用,则公钥一般由用户端产生,如电子邮件程序或浏览器等或者使用第三方开发的具有独立CSP的智能终端如USBkey),CA将根据用户的请求信息产生证书,并用自己的私钥对证书进行签名。其他用户、应用程序或实体将使用CA的公钥对证书进行验证。如果一个CA系统是可信的,则验证证书的用户可以确信,他所验证的证书中的公钥属于证书所代表的那个实体。
CA还负责维护和发布证书废除列表CRL(certificate revocation lists,又称为证书黑名单)。当一个证书,特别是其中的公钥因为其他原因无效时(不是因为到期),CRL提供了一种通知用户和其他应用的中心管理方式。CA系统生成CRL以后,要么是放到LDAP服务器中供用户查询或下载,要么是放置在Web服务器的合适位置,以页面超级连接的方式供用户直接查询或下载。
华丽丽的分割线
回到例子, 在这里, cryptogen 就是一个针对PKI实现的API接口, 在运行完这个task 之后,就会在当前目录下会生成一个crypto-config 目录, 包含了相关的CA 以及证书:
这里是更详细的目录结构图:
要明白这么多目录里面到底有哪些东西, 要先来认识一下配置文件。
crypto-config 文件如下所示, 定义了区块链网络中的Orderer 节点组和Peer 节点组, 以及节点的名称, 域名和节点数等。
在这个文件中, 如果count 多于1个, 例如2, 在生成的文件中就会以peer1, peer1等形式生成相应的文件。
在BYFN 这个例子里面, 定义了OrdererOrg 和PeerOrg 两大节点组, 所以在生成的文件夹crypto-config目录中, 第一层就是ordererOrganizations和peerOrganizations
来看第二层中的文件, 先来看ordererOrganizations目录,第一层是在配置文件中的domain name, 也就是example.com, 下一级目录则包含五个文件夹:
其中ca目录保存的是CA相关的证书, MSP 保存的是会员服务相关的证书, orderers目录则是作为orderer 节点应该持有的证书, tlsca 目录是当开启TLS 协议时的证书, users 则是作为orderer 角色时的用户信息和证书
replacePrivateKeys
replacePrivateKeys 这个task 是generate 功能要执行的第二个方法, 主要的功能是在第一步创建了证书的基础上, 创建两个CA 节点。在前一篇文章中,我们从docker-compose 的配置文件中发现, 只是启动了peer 节点, 但是并没有CA 节点:
那么在这个方法中, 则提供了这个问题的答案, CA 节点以及所需要的证书, 都是在这里生成的。
先来看一下方法定义:
这个方法首先从e2e-tempate的模板文件中复制出一个当前所用的docker-compose 配置文件, 然后用之前生成的证书文件对这个配置文件中的CA证书进行替换。
回忆一下Shell 命令, $(cmd)是替换命令,shell扫描一遍命令行,发现了$(cmd)结构,便将$(cmd)中的cmd执行一次,得到其标准输出,再将此输出放到原来命令PRIV_KEY $(ls *_sk)中的$(ls)位置,即替换了$(ls),再执行PRIV_KEY=命令, 这样就把org1.example.com/ca/目录下的_sk文件 都复制给了PRIV_KEY变量。
另外一个命令是sed, sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用,处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容。
参数s指明是替换操作, 会替换文本中的字符串:
sed 's/book/books/' file
全面替换标记g指明是全局替换, 即使用后缀 /g 标记会替换每一行中的所有匹配:
sed 's/book/books/g' file
在这个方法中的使用的是:
sed $OPTS "s/CA1_PRIVATE_KEY/${PRIV_KEY}/g" docker-compose-e2e.yaml
就是把docker-compose-e2e.yaml文件中的CA1_PRIVATE_KEY替换成变量PRIV_KEY的值。
实际的替换效果是这样的:
可见已经配置好了对ca0 节点的证书。剩下的代码是对ca1的替换, 略。
经过这一步, 证书的配置工作就完成了。
generateChannelArtifacts
在这个方法中, 使用configtxgen 这个命令来产生4个文件:
orderer 起始区块
fabric channel 配置事务
两个 ‘锚’ peer 节点事务--每一个该事务对应一个Peer 节点
orderer 起始区块 就是order service 的创世区块, Channel的事务文件(.tx)会在channel 创建时广岛orderer 节点。而两个peer 事务锚, 如同名字提示的一样, 会在这个channel 中指明每个Org的最开始的peer, 如同轮船上的锚⚓️一样, 以后peer 上的事务都会挂接在这个文件之后。
Configtxgen也会接受一个configtx.yaml作为配置文件。
首先复习一下YAML的基本规则:
大小写敏感
使用缩进表示层级关系
缩进时不允许使用Tab键,只允许使用空格。
缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
YAML支持的数据结构:
对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
纯量(scalars):单个的、不可再分的值
除此之外, 锚点&和别名*,可以用来引用。&用来建立锚点(defaults)<<表示合并到当前数据,*用来引用锚点。
OK, 现在来看这个配置文件:
Profiles:
TwoOrgsOrdererGenesis:
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
TwoOrgsChannel:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
这个文件里面最高一层指明了Profile的结构, 然后是两个创世区块和两个Org。
具体的创建过程如下:
最终生成的文件如下:
好了, 所有的generate 的功能我们都分析完成了, 在接下来的一篇中, 我们将分析up 和e2e的功能, 精彩继续哦。。。