这一节将讨论下面的图所展示的设置描述。特别的,系统是由下面这些实体构成的:成员管理基础架构,如从一个实体集合中区分出不同用户身份的职责(使用系统中任意形式的标识,如:信用卡,身份证),为这个用户注册开户,并生成必要的证书以便通过fabric成功的创建交易,部署或调用链码。
希望使用fabric的用户,通过提供之前所讨论的身份所有权,在成员管理系统中开立一个账户,新的链码被链码创建者(开发)以开发者的形式通过客户端软件部署交易的手段,公布到区块链网络中。这样的交易是第一次被 peer 或验证器接收到,并流传到整个验证器网络中,这个交易被区块链网络执行并找到自己的位置。用户同样可以通过调用交易调用一个已经部署了的链码
下一节提供了由商业目标所驱动的安全性需求的摘要。然后我们游览一下安全组件和它们的操作,以及如何设计来满足安全需求。
这一节表述的与fabric相关的商业安全需求。 身份和角色管理相结合
为了充分的支持实际业务的需求,有必要超越确保加密连续性来进行演进。一个可工作的B2B系统必须致力于证明/展示身份或其他属性来开展业务。商业交易和金融机构的消费交互需要明确的映射到账户的所有者。商务合同通常需要与特定的机构和/或拥有交易的其他特定性质的各方保证有从属关系。身份管理是此类系统的关键组成部分的两个原因是问责制和不可陷害的。
问责制意味着系统的用户,个人或公司,谁的胡作非为都可以追溯到并为自己的行为负责。在很多情况下,B2B系统需要它们的会员使用他们的身份(在某些形式)加入到系统中,以确保问责制的实行。问责制和不可陷害的。都是B2B系统的核心安全需求,并且他们非常相关。B2B系统需要保证系统的诚实用户不会因为其他用户的交易而被指控。
此外,一个B2B系统需要具有可再生性和灵活性,以满足参与者角色和/或从属关系的改变。
交易隐私.
B2B系统对交易的隐私有着强烈的需求,如:允许系统的终端用户控制他与环境交互和共享的信息。例如:一家企业在交易型B2B系统上开展业务,要求它的交易得其他企业不可见,而他的行业合作伙伴无权分享机密信息。
在fabric中交易隐私是通过下面非授权用户的两个属性来实现的:
交易匿名,交易的所有者隐藏在一个被称为匿名集的组建中,在fabric中,它是用户的一个集合。
交易不可关联,同一用户的两个或多个交易不能被关联起来。
根据上下文,非授权用户可以是系统以外的任何人,或用户的子集。
交易隐私与B2B系统的两个或多个成员之间的保密协议的内容强烈相关。任何授权机制的匿名性和不可关联性需要在交易时考虑。
通过身份管理协调交易隐私.
就像文档之后描述的那样,这里所采用的方法是使户隐私来协调身份管理,并使有竞争力的机构可以像下面一样在公共的区块链(用于内部和机构间交易)上快速的交易:
为交易添加证书来实现“有权限的”区块链
使用两层系统:
向登记的证颁发机构(CA)注册来获得(相对的) 静态登记证书 (ECerts)
通过交易CA获取能如实但伪匿名的代表登记用户的交易证书(TCerts).
提供对系统中未授权会员隐藏交易内用的机制
审计支持. 商业系统偶尔会受到审核。在这种情况下,将给予审计员检查某些交易,某组交易,系统中某些特定用户或系统自己的一些操作的手段。因此,任意与商业伙伴通过合同协议进行交易的系统都应该提供这样的能力。
成员管理服务是由网络上管理用户身份和隐私的几个基础架构来组成的。这些服务验证用户的身份,在系统中注册用户,并为他/她提供所有作为可用、兼容的参数者来创建和/或调用交易所需要的证书。公告密钥体系(Public Key Infrastructure ,PKI)是一个基于不仅对公共网络上交换的数据的加密而且能确认对方身份的公共密钥加密的。PKI管理密钥和数字证书的生成,发布和废止。数字证书是用来建立用户证书,并对消息签名的。使用证书签名的消息保证信息不被篡改。典型的PKI有一个证书颁发机构(CA),一个登记机构(RA),一个证书数据库,一个证书的存储。RA是对用户进行身份验证,校验数据的合法性,提交凭据或其他证据来支持用户请求一个或多个人反映用户身份或其他属性的可信任机构。CA根据RA的建议为特定的用户发放根CA能直接或分级的认证的数字证书。另外,RA的面向用户的通信和尽职调查的责任可以看作CA的一部分。成员服务由下图展示的实体组成。整套PKI体系的引入加强了B2B系统的强度(超过,如:比特币)
根证书颁发机构(根CA): 它代表PKI体系中的信任锚。数字证书的验证遵循信任链。根CA是PKI层次结构中最上层的CA。
登记机构(RA): 它是一个可以确定想要加入到带权限区块链的用户的有效性和身份的可信实体。它是负责与用户外的带外通信来验证他/她的身份和作用。它是负责与用户进行频外通信来验证他/她的身份和角色。它创建登记时所需要的注册证书和根信任上的信息。
注册证书颁发机构(ECA): 负责给通过提供的注册凭证验证的用户颁发注册证书(ECerts)
交易认证中心(TCA): 负责给提供了有效注册证书的用户颁发交易证书(TCerts)
TLS证书颁发机构(TLS-CA): 负责签发允许用户访问其网络的TLS证书和凭证。它验证用户提供的包含该用户的特定信息的,用来签发TLS证书的,证书或证据。
注册证书(ECerts) ECerts是长期证书。它们是颁发给所有角色的,如用户,非验证 peer,验证 peer。在给用户颁发的情况下,谁向区块链提交候选人申请谁就拥有TCerts(在下面讨论),ECerts有两种可能的结构和使用模式:
Model A: ECerts 包含所有者的身份/注册ID,并可以在交易中为TCert请求提供只用来对名义实体身份做验证。它们包含两个密钥对的公共部分:签名密钥对和加密/密钥协商密钥对。 ECerts是每个人都可以访问。
Model B: ECerts 包含所有者的身份/注册ID,并只为TCert请求提供名义实体的身份验证。它们包含一个签名密钥对的公共部分,即,签名验证公钥的公共部分。作为依赖方,ECerts最好只由TCA和审计人员访问。他们对交易是不可见的,因此(不像TCerts)签名密钥对不在这一层级发挥不可抵赖的作用。
交易证书(TCerts) TCerts是每个交易的短期证书。它们是由TCA根据授权的用户请求颁发的。它们安全的给一个交易授权,并可以被配置为隐藏谁参与了交易或选择性地暴露这样身份注册ID这样的信息。他们包含签名密钥对的公共部分,并可以被配置为包含一个密钥协议的密钥对的公共部分。他们仅颁发给用户。它们唯一的关联到所有者,它们可以被配置为这个关联只有TCA知道知道(和授权审核员)。TCert可以配置成不携带用户的身份信息。它们使得用户不仅以匿名方式参与到系统中,而且阻止了交易之间的关联性。
然而,审计能力和问责制的要求TCA能够获取给定身份的TCert,或者获取指定TCert的所有者。有关TCerts如何在部署和调用交易中使用的详细信息参见4.3节,交易安全是在基础设施层面提供的。
TCerts可容纳的加密或密钥协议的公共密钥(以及数字签名的验证公钥)。 如果配备好TCert,那么就需要注册证书不能包含加密或密钥协议的公钥。
这样的密钥协议的公钥,Key_Agreement_TCertPub_Key,可以由交易认证机构(TCA)使用与生成Signature_Verification_TCertPub_Key同样的方法,使用TCertIndex + 1 而不是TCertIndex来作为索引个值来生成,其中TCertIndex是由TCA为了恢复而隐藏在TCert中的。
交易证书(TCert)的结构如下所述:
这里至少有三种方式来配置考虑了隐藏注册ID域密钥的分配方案: (a) Pre-K在注册期间发给用户,peer 和审计员,并对TCA和授权的审计员可用。它可能,例如由Kchain派生(会在这个规范的后面描述)或为了链码的保密性使用独立的key(s)。
(b) Pre-K对验证器,TCA和授权的审计员可用。K是在验证器成功响应用户的查询交易(通过TLS)后可用给的。查询交易可以使用与调用交易相同的格式。对应下面的例1,如果查询用户又有部署交易的ACL中的一张TCert,那么就可以得到创建这个部署交易的用户的注册ID(enrollmentID)。对应下面的例2,如果查询所使用TCert的注册ID(enrollmentID)与部署交易中访问控制域的其中一个隶属关系/角色匹配,那么就可以得到创建这个部署交易的用户的注册ID(enrollmentID)。
Example 1:
Example 2:
(c) Pre-K对TCA和授权的审计员可用。对于批量中的所有TCert,TCert特有的K可以和TCert一起分发给TCert的所有者(通过TLS)。这样就通过K的TCert所有者启用目标释放(TCert所有者的注册ID的可信通知)。这样的目标释放可以使用预定收件人的密钥协商公钥和/或PKchain其中SKchain就像规范的后面描述的那样对验证器可用。这样目标释放给其它合同的参与者也可以被纳入到这个交易或在频外完成。
如果TCert与上述的ECert模型A的结合使用,那么使用K不发送给TCert的所有者的方案(c)就足够了。 如果TCert与上述的ECert模型A的结合使用,那么TCert中的密钥协商的公钥域可能就不需要了。
交易认证中心(TCA)以批量的方式返回TCert,每个批量包含不是每个TCert都有的,但是和TCert的批量一起传递到客户端的KeyDF_Key(Key-Derivation-Function Key) (通用TLS)。KeyDF_Key允许TCert的拥有者派生出真正用于从AES_EncryptTCertOwner_EncryptKey(TCertIndex || 已知的填充/校验检查向量)的TCertIndex恢复的TCertOwner_EncryptKey。
TLS证书(TLS-Certs) TLS-Certs 是用于系统/组件到系统/组件间通讯所使用的证书。他们包含所有者的身份信息,使用是为了保证网络基本的安全。
成员管理的这个实现提供下面描述的基础功能:ECerts是没有到期/废止的;TCert的过期是由验证周期的时间窗口提供的。TCerts是没有废止的。ECA,TCA和TLS CA证书是自签名的,其中TLS CA提供信任锚点。
下面这个图高度概括了用户注册过程,它具有离线和在线阶段。
离线处理: 在第一步中,每个用户/非验证 peer /验证 peer 有权在线下将较强的识别凭证(身份证明)到导入到注册机构(RA)。这需要在频外给RA提供为用户创建(存储)账号的证据凭证。第二步,RA返回对应的用户名/密码和信任锚点(这个实现中是TLS-CA Cert)给用户。如果用户访问了本地客户端,那么这是客户端可以以TLS-CA证书作为信任锚点来提供安全保障的一种方法。
在线阶段: 第三步,用户连接客户端来请求注册到系统中。用户发送它的用户名和密码给客户端。客户端代表用户发送请求给PKI框架。第四步,接受包,第五步,包含其中一些对应于由客户端私有/秘密密钥的若干证书。一旦客户端验证包中所有加密材料是正确/有效的,他就把证书存储在本地并通知用户。这时候用户注册就完成了。
图4展示了注册的详细过程。PKI框架具有RA, ECA, TCA和TLS-CA这些实体。第一步只收,RA调用“AddEntry”函数为它的数据库输入(用户名/密码)。这时候用户已正式注册到系统数据库中。客户端需要TLS-CA证书(当作信任锚点)来验证与服务器之间的TLS握手是正确的。第四步,客户端发送包含注册公钥和像用户名,密码这样的附加身份信息的注册请求到ECA(通过TLS备案层协议)。ECA验证这个用户是否真实存在于数据库。一旦它确认用户有权限提交他/她的注册公钥,那么ECA就会验证它。这个注册信息是一次性的。ECA会更新它的数据库来标识这条注册信息(用户名,密码)不能再被使用。ECA构造,签名并送回一张包含用户注册公钥的(步骤5)注册证书(ECert)。它同样会发送将来会用到(客户端需要向TCA证明他/她的ECert使用争取的ECA创建的)的ECA证书(ECA-Cert))。(尽管ECA-Cert在最初的实现中是自签名的,TCA,TLS-CA和ECA是共址)第六步,客户端验证ECert中的公钥是最初由客户端提交的(即ECA没有作弊)。它同样验证ECert中的所有期望的信息存在且形式正确。
同样的,在第七步,客户端发送包含它的公钥和身份的注册信息到TLS-CA。TLS-CA验证该用户在数据库中真实存在。TLS-CA生成,签名包含用户TLS公钥的一张TLS-Cert(步骤8)。TLS-CA发送TLS-Cert和它的证书(TLS-CA Cert)。第九步类似于第六步,客户端验证TLS Cert中的公钥是最初由客户端提交的,TLS Cert中的信息是完整且形式正确。在第十步,客户端在本地存储中保存这两张证书的所有证书。这时候用户就注册完成了。
在这个版本的实现中验证器的注册过程和 peer 的是一样的。尽管,不同的实现可能使得验证器直接通过在线过程来注册。
客户端: 请求TCert批量需要包含(另外计数),ECert和使用ECert私钥签名的请求(其中ECert的私钥使用本地存储获取的)
TCA为批量生成TCerts: 生成密钥派生函数的密钥,KeyDF_Key, 当作HMAC(TCA_KDF_Key, EnrollPub_Key). 为每张TCert生成公钥(使用TCertPub_Key = EnrollPub_Key + ExpansionValue G, 其中384位的ExpansionValue = HMAC(Expansion_Key, TCertIndex) 和384位的Expansion_Key = HMAC(KeyDF_Key, “2”)). 生成每个AES_EncryptTCertOwner_EncryptKey(TCertIndex || 已知的填充/校验检查向量), 其中|| 表示连接,且TCertOwner_EncryptKey被当作[HMAC(KeyDF_Key, “1”)]派生256位截断.
客户端: 为部署,调用和查询,根据TCert来生成TCert的私钥:KeyDF_Key和ECert的私钥需要从本地存储中获取。KeyDF_Key是用来派生被当作[HMAC(KeyDF_Key, “1”)]256位截断的TCertOwner_EncryptKey;TCertOwner_EncryptKey是用来对TCert中的 AES_EncryptTCertOwner_EncryptKey(TCertIndex || 已知的填充/校验检查向量)域解密的;TCertIndex是用来派生TCert的私钥的: TCertPriv_Key = (EnrollPriv_Key + ExpansionValue)模n,其中384位的ExpansionValue = HMAC(Expansion_Key, TCertIndex),384位的Expansion_Key = HMAC(KeyDF_Key, “2”)。
实际是支持交易证书过期的。一张交易证书能使用的时间窗是由‘validity period’标识的。实现过期支持的挑战在于系统的分布式特性。也就是说,所有验证实体必须共享相同的信息;即,与交易相关的有效期验证需要保证一致性。为了保证有效期的验证在所有的验证器间保持一致,有效期标识这一概念被引入。这个标识扮演着逻辑时钟,使得系统可以唯一识别有效期。在创世纪时,链的“当前有效期”由TCA初始化。至关重要的是,此有效期标识符给出随时间单调增加的值,这使得它规定了有效期间总次序。
对于指定类型的交易,系统交易有效周期标识是用来一起向区块链公布有效期满的。系统交易涉及已经在创世纪块被定义和作为基础设施的一部分的合同。有效周期标识是由TCA周期性的调用链码来更新的。注意,只有TCA允许更新有效期。TCA通过给定义了有效期区间的‘not-before’和‘not-after’这两个域设置合适的整数值来为每个交易证书设置有效期。
TCert过期: 在处理TCert时,验证器从状态表中读取与总账中的‘current validity period’相关的值来验证与交易相关的外部证书目前是否有效。状态表中的当前值需要落在TCert的‘not-before’和‘not-after’这两个子域所定义的区间中。如果满足,那么验证器就继续处理交易。如果当前值没有在这个区间中,那么TCert已经过期或还没生效,那么验证器就停止处理交易。
ECert过期: 注册证书与交易证书具有不同的有效期长度。
废止是由证书废止列表(CRLs)来支持的,CRLs鉴定废止的证书。CRLs的改变,增量的差异通过区块链来公布
fabric中的交易是通过提交用户-消息来引入到总账中的。就像之前章节讨论的那样,这些信息具有指定的结构,且允许用户部署新的链码,调用已经存在的链码,或查询已经存在的链码的状态。因此交易的方式被规范,公布和处理在整个系统提供的隐私和安全中起着重要的作用。
一方面我们的成员服务通过检查交易是由系统的有效用户创建的来提供验证交易的手段,为了把用户身份和交易撇清,但是在特定条件下又需要追踪特定个体的交易(执法,审计)。也就是说,成员服务提供结合用户隐私与问责制和不可抵赖性来提供交易认证机制。
另一方面,fabric的成员服务不能单独提供完整的用户活动隐私。首先fabric提供完整的隐私保护条款,隐私保护认证机制需要通过交易保密协同。很明显,如果认为链码的内容可能会泄漏创建者的信息,那么这就打破了链码创建者的隐私要求。第一小节讨论交易的保密性。
为链码的调用强制访问控制是一个重要的安全要求。fabric暴露给应用程序(例如,链码创建者)这意味着当应用利用fabric的成员服务是,需要应用自己调用访问控制。4.4节详细阐述了这一点。
重放攻击是链码安全的另一个重要方面,作为恶意用户可能复制一个之前的,已经加入到区块链中的交易,并向网络重放它来篡改它的操作。这是第4.3.3节的话题。
本节的其余部分介绍了基础设施中的安全机制是如何纳入到交易的生命周期中,并分别详细介绍每一个安全机制。
交易在客户端创建。客户端可以是普通的客户端,或更专用的应用,即,通过区块链处理(服务器)或调用(客户端)具体链码的软件部分。这样的应用是建立在平台(客户端)上的,并在4.4节中详细介绍。
新链码的开发者可以通过这些fabric的基础设施来新部署交易:
具有保密限制的链码的调用和查询交易都是用类似的方式创建。交易者提供需要执行的链码的标识,要调用的函数的名称及其参数。可选的,调用者可以传递在链码执行的时候所需要提供的代码调用元数据给交易创建函数。交易元数据是调用者的应用程序或调用者本身为了它自己的目的所使用的另外一个域。
最后,交易在客户端,通过它们的创建者的证书签名,并发送给验证器网络。 验证器接受私密交易,并通过下列阶段传递它们:
在开发人员的要求下,交易机密性要求链码的原文,即代码,描述,是不能被未授权的实体(即,未被开发人员授权的用户或 peer)访问或推导(assuming a computational attacker)出来。对于后者,部署和调用交易的内容始终被隐藏对链码的保密需求是至关重要的。本着同样的精神,未授权方,不应该能联系链码(调用交易)与链码本身(部署交易)之间的调用关系或他们之间的调用。
任何候选的解决方案的附加要求是,满足并支持底层的成员服务的隐私和安全规定。此外,在fabric中他不应该阻止任何链码函数的调用访问控制,或在应用上实现强制的访问控制机制(参看4.4小结)。
下面提供了以用户的粒度来设置的交易机密性机制的规范。最后小结提供了一些如何在验证器的层次来扩展这个功能的方针。当前版本所支持的特性和他的安全条款可以在4.7节中找到。
目标是达到允许任意的子集实体被允许或限制访问链码的下面所展示的部分: 1. 链码函数头,即,包含在链码中函数的原型
注意,这样的设计为应用提供利用fabric的成员管理基础设施和公钥基础设施来建立自己的访问控制策略和执法机制的能力。
为了支持细粒度的保密控制,即,为链码创建者定义的用户的子集,限制链码的明文读权限,一条绑定到单个长周期的加密密钥对的链(PKchain, SKchain)。
尽管这个密钥对的初始化是通过每条链的PKI来存储和维护的,在之后的版本中,这个限制将会去除。链(和相关的密钥对)可以由任意带有特定(管理)权限的用户通过区块链来触发(参看4.3.2.2小节)
搭建. 在注册阶段, 用户获取(像之前一样)一张注册证书,为用户ui标记为Certui,其中每个验证器vj获取的注册证书标记为Certvj。注册会给用户或验证器发放下面这些证书:
用户:
a. 声明并授予自己签名密钥对(spku, ssku)
b. 申明并授予他们加密密钥对(epku, esku),
c. 获取链PKchain的加密(公共)密钥
验证器:
a. 声明并授予他们签名密钥对(spkv, sskv)
b. 申明并授予他们加密密钥对 (epkv, eskv),
c. 获取链SKchain的解密(秘密)密钥
因此,注册证书包含两个密钥对的公共部分:
链,验证器和用户注册公钥是所有人都可以访问的。
除了注册证书,用户希望通过交易证书的方式匿名的参与到交易中。用户的简单交易证书ui被标记为TCertui。交易证书包含的签名密钥对的公共部分标记为(tpkui,tskui)。
下面的章节概括性的描述了如何以用户粒度的方式提供访问控制。
部署交易的结构. 下图描绘了典型的启用了保密性的部署交易的结构。
注意,部署交易由几部分组成:
合同用户部分: 合同用户的公共密钥,即具有部分链码读权限的用户,根据他们的访问权限加密密钥:
SKc使得用户能读取与这段链码相关的任意信息(调用,状态,等)
KC使用户只能读取合同代码
KH 使用户只能读取头信息
KS使用户只能读取与合同相关的状态
最后给用户发放一个合同的公钥PKc,使得他们可以根据合同加密信息,从而验证器(or any in possession of SKc)可以读取它。每个合同用户的交易证书被添加到交易中,并跟随在用户信息之后。这可以使得用户可以很容易的搜索到有他们参与的交易。注意,为了信函可以在本地不保存任何状态的情况下也能通过分析总账来获取这笔交易,部署交易也会添加信息到链码创建者uc。
整个交易由链码的创建者的证书签名,即:有信函决定使用注册还是交易证书。 两个值得注意的要点:
调用交易的结构. 下图结构化描述了,交易调用链码会触发使用用户指定的参数来执行链码中的函数
调用交易和部署交易一样由一个基本信息, 代码信息,链验证器和一个合同用户,并使用一张调用者的交易证书对所有进行签名。
基本信息 与部署交易中对应部分遵循相同的结构。唯一的不同是交易类型被设置为''InvocTx'',链码的标识符或名字是通过链指定的加密(公共)密钥来加密的。
代码信息 部署交易中的对应结构具有相同展现。在部署交易中作为代码有效载荷,现在由函数调用明细(调用函数的名字,对应的参数),由应用提供的代码元数据和交易创建者(调用者 u)的证书,TCertu。在部署交易的情况下,代码有效载荷和是通过调用者u的交易证书TCertu签名的。在部署交易的情况下,代码元数据,交易数据是由应用提供来使得信函可以实现他自己的访问控制机制和角色(详见4.4节)。
最后,合同用户和链验证器部分提供密钥和有效荷载是使用调用者的密钥加密的,并分别链加密密钥。在收到此类交易,验证器解密 [code-name]PKchain使用链指定的密钥SKchain ,并获取被调用的链码身份。给定的信封,验证器从本地的获取链码的解密密钥SKc,并使用他来解密链验证器的信息,使用对称密钥 KI对调用交易的有效荷载加密。给定信函,验证器解密代码信息,并使用指定的参数和附加的代码元数据(参看4.4节的代码元数据详细信息)执行链码。当链码执行后,链码的状态可能就更新了。 加密所使用的状态特定的密钥Ks在链码部署的时候就定义了。尤其是,在当前版本中Ks 和KiTx被设计成一样的(参看4.7节)。
查询交易的结构. 查询交易和调用交易具有同样的格式。唯一的区别是查询交易对链码的状态没有影响,且不需要在执行完成之后获取(解密的)并/或更新(加密的)状态。
这节阐述了如何处理当前链中的不同(或子集)集合的验证器下的一些交易的执行。本节中抑制IP限制,将在接下的几个星期中进行扩展。
在重放攻击中,攻击者“重放”他在网络上“窃听”或在区块链''看到''的消息
由于这样会导致整个验证实体重做计算密集型的动作(链码调用)和/或影响对应的链码的状态,同时它在攻击侧又只需要很少或没有资源,所以重放攻击在这里是一个比较大的问题。如果交易是一个支付交易,那么问题就更大了,重放可能会导致在不需要付款人的参与下,多于一次的支付。
当前系统使用以下方式来防止重放攻击:
其他资产管理系统,即比特币,虽然没有直接处理重放攻击,但它防止了重放。在管理(数字)资产的系统中,状态是基于每个资产来维护的,即,验证器只保存谁拥有什么的记录。因为交易的重放根据协议(因为只能由资产/硬币旧的所有者衍生出来)可以直接认为无效的,所以防重放攻击是这种方式的直接结果。尽管这合适资产管理系统,但是这并不表示在更一般的资产管理中需要比特币系统。
在fabric中,防重放攻击使用混合方法。
这就是,用户在交易中添加一个依赖于交易是匿名(通过交易证书签名)或不匿名(通过长期的注册证书签名)来生成的nonce。更具体的:
用户通过注册证书来提交的交易需要包含nonce。其中nonce是在之前使用同一证书的交易中的nonce函数(即计数器或哈希)。包含在每张注册证书的第一次交易中的nonce可以是系统预定义的(即,包含在创始块中)或由用户指定。在第一种情况中,创世区块需要包含nonceall,即,一个固定的数字和nonce被用户与身份IDA一起用来为他的第一笔注册证书签名的交易将会
nonceround0IDA <- hash(IDA, nonceall), 其中IDA出现在注册证书中。从该点之后的这个用户关于注册证书的连续交易需要包含下面这样的nonce nonceroundiIDA <- hash(nonceround{i-1}IDA), 这表示第i次交易的nonce需要使用这样证书第{i-1}次交易的nonce的哈希。验证器持续处理他们收到的只要其满足上述条件的交易。一旦交易格式验证成功,验证器就使用nonce更新他们的数据库。存储开销:
在用户侧:只有最近使用的nonce
在验证器侧: O(n), 其中n是用户的数量
用户使用交易证书提交的交易需要包含一个随机的nonce,这样就保证两个交易不会产生同样的哈希。如果交易证书没有过期的话,验证器就向本地数据库存储这笔交易的哈希。为了防止存储大量的哈希,交易证书的有效期被利用。特别是验证器为当前或未来有效周期来维护一个接受交易哈希的更新记录。
存储开销 (这里只影响验证器): O(m), 其中m近似于有效期内的交易和对应的有效标识的数量(见下方)
应用是抱在区块链客户端软件上的一个具有特定功能的软件。如餐桌预订。应用软件有一个版本开发商,使后者可以生成和管理一些这个应用所服务的行业所需要的链码,而且,客户端版本可以允许应用的终端用户调用这些链码。应用可以选择是否对终端用户屏蔽区块链。
本节介绍应用中如何使用链码来实现自己的访问控制策略,并提供如何使用成员服务来达到相同的目的。
这个报告可以根据应用分为调用访问控制,和读取访问控制。
为了允许应用在应用层安全的实现自己的访问问控制,fabric需要提供特定的支持。在下面的章节中,我们详细的说明的fabric为了达到这个目的而给应用提供的工具,并为应用如何来使用它们使得后者能安全的执行访问控制提供方针。
来自基础设施的支持. 把链码的创建者标记为 uc,为了安全的实现应用层自己的调用访问控制,fabric必须需要提供特定的支持。
更具体的,fabric层提供下面的访问能力:
客户端-应用可以请求fabric使用指定的客户端拥有的交易证书或注册证书来签名和验证任何消息; 这是由Certificate Handler interface来处理的。
客户端-应用可以请求fabric一个绑定将身份验证数据绑定到底层的交易传输的应用程序;这是由Certificate Handler interface来处理的。
为了支持交易格式,允许指定被传递给链码在部署和调用时间的应用的元数据;后者被标记为代码元数据。
Certificate Handler接口允许使用底层证书的密钥对来对任意消息进行签名和验证。证书可以是TCert或ECert。
// CertificateHandler exposes methods to deal with an ECert/TCert
type CertificateHandler interface {
// GetCertificate returns the certificate's DER
GetCertificate() []byte
// Sign signs msg using the signing key corresponding to the certificate
Sign(msg []byte) ([]byte, error)
// Verify verifies msg using the verifying key corresponding to the certificate
Verify(signature []byte, msg []byte) error
// GetTransactionHandler returns a new transaction handler relative to this certificate
GetTransactionHandler() (TransactionHandler, error)
}
Transaction Handler借口允许创建交易和访问可利用的底层绑定来链接应用数据到底层交易。绑定是在网络传输协议引入的概念(参见,https://tools.ietf.org/html/rfc5056)记作*通道绑定*,*允许应用在网络层两端的建立安全通道,与在高层的认证绑定和在低层是一样的。 这允许应用代理保护低层会话,这具有很多性能优势。* 交易绑定提供识别fabric层次交易的身份,这就是应用数据要加入到总账的容器。
// TransactionHandler represents a single transaction that can be uniquely determined or identified by the output of the GetBinding method.
// This transaction is linked to a single Certificate (TCert or ECert).
type TransactionHandler interface {
// GetCertificateHandler returns the certificate handler relative to the certificate mapped to this transaction
GetCertificateHandler() (CertificateHandler, error)
// GetBinding returns a binding to the underlying transaction (container)
GetBinding() ([]byte, error)
// NewChaincodeDeployTransaction is used to deploy chaincode
NewChaincodeDeployTransaction(chaincodeDeploymentSpec *obc.ChaincodeDeploymentSpec, uuid string) (*obc.Transaction, error)
// NewChaincodeExecute is used to execute chaincode's functions
NewChaincodeExecute(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string) (*obc.Transaction, error)
// NewChaincodeQuery is used to query chaincode's functions
NewChaincodeQuery(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string) (*obc.Transaction, error)
}
对于版本1,绑定由hash(TCert, Nonce)组成,其中TCert是给整个交易签名的交易证书,Nonce是交易所使用的nonce。
Client接口更通用,提供之前接口实例的手段。
type Client interface {
...
// GetEnrollmentCertHandler returns a CertificateHandler whose certificate is the enrollment certificate
GetEnrollmentCertificateHandler() (CertificateHandler, error)
// GetTCertHandlerNext returns a CertificateHandler whose certificate is the next available TCert
GetTCertificateHandlerNext() (CertificateHandler, error)
// GetTCertHandlerFromDER returns a CertificateHandler whose certificate is the one passed
GetTCertificateHandlerFromDER(der []byte) (CertificateHandler, error)
}
为了向链码调用控制提供应用级别的的访问控制列表,fabric的交易和链码指定的格式需要存储在应用特定元数据的额外的域。 这个域在图1中通过元数据展示出来。这个域的内容是由应用在交易创建的时候决定的。fabric成把它当作非结构化的字节流。
message ChaincodeSpec {
...
ConfidentialityLevel confidentialityLevel;
bytes metadata;
...
}
message Transaction {
...
bytes payload;
bytes metadata;
...
}
为了帮助链码执行,在链码调用的时候,验证器为链码提供额外信息,如元数据和绑定。
应用调用访问控制. 这一节描述应用如何使用fabric提供的手段在它的链码函数上实现它自己的访问控制。 这里考虑的情况包括:
C: 是只包含一个函数的链码,如,被成为hello
uc: 是C的部署;
ui: 是被授权调用C的用户。用户uc希望只有ui可以调用函数hello
链码部署: 在部署的时候,uc具有被部署交易元数据的完全控制权,可硬存储一个ACL的列表(每个函数一个),或一个应用所需要的角色的列表。存储在ACL中的格式取决于部署的交易,链码需要在执行时解析元数据。 为了定义每个列表/角色,uc可以使用ui的任意TCerts/Certs(或,如果可接受,其他分配了权限或角色的用户)。把它记作TCertui。 开发者和授权用户之间的TCerts和 Certs交换实在频外渠道进行的。
假设应用的uc需要调用 hello函数,某个消息M就被授权给授权的调用者(在我们的例子中是ui)。 可以区分为以下两种情况:
M是链码的其中一个函数参数;
M是调用信息本事,如函数名,函数参数。
链码调用: 为了调用C, ui的应用需要使用TCert/ECert对M签名,用来识别ui在相关的部署交易的元数据中的参与身份。即,TCertui。更具体的,ui的客户端应用做一下步骤:
Certui, cHandler获取CertificateHandler
获取新的TransactionHandler来执行交易, txHandler相对与他的下一个有效的TCert或他的ECert
通过调用txHandler.getBinding()来得到txHandler的绑定
通过调用cHandler.Sign('M* || txBinding')来对'M || txBinding'签名, *sigma是签名函数的输出。
通过调用来发布一个新的执行交易,txHandler.NewChaincodeExecute(...). 现在, sigma可以以一个传递给函数(情形1)参数或payload的元数据段的一部分(情形2)的身份包含在交易中。
链码处理: 验证器, 从ui处接受到的执行交易将提供以下信息:
执行交易的绑定,他可以在验证端独立的执行;
执行交易的元数据(交易中的代码元数据);
部署交易的元数据(对应部署交易的代码元数据组建).
注意sigma是被调用函数参数的一部分,或者是存储在调用交易的代码元数据内部的(被客户端应用合理的格式化)。 应用ACL包含在代码元数据段中,在执行时同样被传递给链码。
函数hello负责检查sigma的确是通过TCertui在'M || txBinding'上的有效签名。
这节描述fabric基础设施如何支持应用在用户层面执行它自己的读访问控制策略。和调用访问控制的情况一样,第一部分描述了可以被应用程序为实现此目的利用的基础设施的功能,接下来介绍应用使用这些工具的方法。
为了说明这个问题,我们使用和指点一样的例子,即:
C: 是只包含一个函数的链码,如,被成为hello
uA: 是C的部署者,也被成为应用;
ur: 是被授权调用C的用户。用户uA希望只有ur可以读取函数hello
来自基础设施的支持. 为了让uA在应用层安全的实现自己的读取访问控制我们的基础设施需要像下面描述的那样来支持代码的部署和调用交易格式。
更具体的fabric层需要提供下面这些功能:
为数据只能通过验证(基础设施)侧解密,提供最低限度的加密功能;这意味着基础设施在我们的未来版本中应该更倾向于使用非对称加密方案来加密交易。更具体的,在链中使用在上图中标记为 Kchain 的非对称密钥对。具体参看交易保密小节
客户端-引用可以请求基础设施,基于客户端侧使用特定的公共加密密钥或客户端的长期解密密钥来加密/解密信息。
交易格式提供应用存储额外的交易元数据的能力,这些元数据可以在后者请求后传递给客户端应用。交易元数据相对于代码元数据,在执行时是没有加密或传递给链码的。因为验证器是不负责检查他们的有效性的,所以把它们当作字节列表。
应用读访问控制. 应用可以请求并获取访问用户ur的公共加密密钥,我们把它标记为PKur。可选的,ur 可能提供 uA的一张证书给应用,使应用可以利用,标记为TCertur。如:为了跟踪用户关于应用的链码的交易。TCertur和PKur实在频外渠道交换的。
部署时,应用 uA执行下面步骤:
使用底层基础设施来加密C的信息,应用使用PKur来访问ur。标记Cur为得到的密文。
(可选) Cur可以和TCertur连接
保密交易被构造为''Tx-metadata''来传递
在调用的时候,在 ur节点上的客户端-应用可以获取部署交易来得到C的内容。
这只需要得到相关联的部署交易的 tx-metadata域,并触发区块链基础设施客户端为Cur提供的解密函数。注意,为ur正确加密C是应用的责任。
此外,使用tx-metadata域可以一般性的满足应用需求。即,调用者可以利用调用交易的同一域来传递信息给应用的开发者。
Important Note: 要注意的是验证器在整个执行链码过程中不提供任何解密预测。 对payload解密由基础设施自己负责(以及它附近的代码元数据域)。并提供他们给部署/执行的容器。
这一节描述了钱包服务的安全设计,这是一个用户可以注册,移动他们的秘密材料到,办理交易的节点。
由于钱包服务是一个用户秘密材料所有权的服务,所以要杜绝没有安全授权机制的恶意钱包服务可以成功模拟客户。
因此,我们强调的是,设计一种值得信赖的,只有在代表用户的客户端同意的情况下,钱包服务才能执行交易。 这里有两种终端用户注册到在线钱包服务的情况:
当用户注册到注册机构并获得他/她的
,但是没有安装客户端来触发完整的注册过程。
用户已经安装客户端并完成注册阶段
首先,用户与在线钱包服务交互,允许他们进行身份验证的钱包服务发布证书。即用户给定用户名和密码,其中用户名在成员服务中识别用户,标记为AccPub,密码是关联的秘密,标记为AccSec,这是由用户和服务分享的。
为了通过在线钱包服务注册,用户必须提供下面请求对象到钱包服务:
AccountRequest /* account request of u \*/
{
OBCSecCtx , /* credentials associated to network \*/
AccPubu, /* account identifier of u \*/
AccSecProofu /* proof of AccSecu\*/
}
OBCSecCtx指向用户证书,它依赖于注册过程中的阶段。可以是用户的注册ID和密码,
或他的注册证书和关联的密钥(ECertu, sku), 其中 sku是用户签名和解密密钥的简化标记。
OBCSecCtx需要给在线钱包服务必要的信息来注册用户和发布需要的TCerts。
对于后续的请求,用户u需要提供给钱包服务的请求与虾子面这个格式类似。
TransactionRequest /* account request of u \*/
{
TxDetails, /* specifications for the new transaction \*/
AccPubu, /* account identifier of u \*/
AccSecProofu /* proof of AccSecu \*/
}
这里,TxDetails指向在线服务代表用户构造交易所需要的信息,如类型,和用户指定的交易的内容。
AccSecProofu是对应请求中剩下的域的使用共享密钥的HMAC。
Nonce-based方法与我们在fabric中一样可以防止重放攻击。
TLS连接可以用在每种服务器端认证的情况,在网络层对请求加密(保密,防止重放攻击,等)
TLS CA需要给(非验证)peer,验证器,和单独的客户端(或具有存储私钥的游览器)发放TLS证书的能力。最好,这些证书可以使用之前的类型来区分。
各个类型的CA(如TLS CA, ECA, TCA)的TLS证书有可以通过中间CA(如,一个根CA的下属CA)发放。这里没有特定流量分析的问题,任意给定的TLS连接都可以相互验证,除了请求TLS CA的TLS证书的时候。
在当前的实现中,唯一的信任锚点是TLS CA的自签名证书来适应与所有三个(共址)服务器(即TLS CA,TCA和ECA)进行通信的单个端口限制。因此,与TLS CA的TLS握手来与TLS CA建立连接,所得到的会话密钥会传递给共址的TCA和ECA。因此,TCA和ECA的自签名证书的有效性的信任继承自对TLS CA的信任。在不提高TLS CA在其他CA之上的实现中,信任锚点需要由TLS CA和其他CA都认证的根CA替代。
这一小节列出了当前版本的fabric的限制。 具体的关注点是客户端操作和交易保密性设计,如4.7.1和4.7.2所述。
客户端的注册和交易的创建是由非验证 peer 以在线钱包的角色全部执行的。 集体的,终端用户利用注册证书 在非验证 peer 开立账户,并使用这些证书进一步授权 peer 建立代表用户的交易。 需要注意的是,这样的设计不会为 peer 代表用户提交的交易提供安全授权,如恶意 peer 可以模拟用户。 网上钱包的涉及安全问题设计规范的详细信息,可以在4.5节找到。 目前用户可以注册和执行交易的 peer 数量是一。
免责声明: 当前版本的交易保密是最小的,这被用来作为中间步骤来达到允许在未来版本中的细粒度(调用)的访问控制的执行设计。
在当前的格式,交易的保密仅仅在链层面提供,即,保存在总账中的交易内容对链的所有成员,如,验证器和用户,都是可读的。于此同时,不是系统的成员的应用审计人员,可以给予被动的观察区块链数据的手段。同时保证给予他们只是为了与被审计应用程序相关的交易。状态通过一种加密,同时不破坏底层共识网络的正常运行的方式来满足这样的审计要求
更具体的,当前使用对称密钥加密来提供交易保密性。
在这种背景下,一个最主要的挑战是特定于区块链的设置,验证器需要在区块链的状态上打成共识,即,除了交易本身,还包括个人合同或链码的状态更新。 虽然对于非机密链码这是微不足道的,对于机密链码,需要设计状态的加密机制,使得所得的密文语义安全,然而,如果明文状态是相同的那么他们就相等。
为了克服这一难题,fabric利用了密钥的层级,使用相同的密钥进行加密来降低密文数。同时,由于部分这些密钥被用于IV的生成,这使得验证方执行相同的事务时产生完全相同的密文(这是必要的,以保持不可知到底层共识算法),并通过只披露给审计实体最相关的密钥来提供控制审计的可能性。
方法描述: 成员服务为总账生成对称密钥 (Kchain),这是在注册到区块链系统所有实体时发布的,如,客户端和验证实体已通过链的成员服务发放证书。 在注册阶段,用户获取(像之前一样)一张注册证书,为用户ui记作Certui,每个验证器vj获取它的被记作Certvj的证书。
实体注册将得到提高,如下所示。除了注册证书,用户希望以匿名方式参与交易发放交易证书。 为了简化我们把用户 ui 的交易证书记作 TCertui。
交易证书包含签名密钥对的公共部分记作 (tpkui,tskui)。
为了防止密码分析和执行保密,下面的密钥层级被用来生成和验证保密的交易: 为了提交保密交易(Tx)到总账,客户端首先选择一个nonce(N),这是需要提交区块链的所有交易中是唯一的,并通过以Kchain作为密钥,nonce作为输入的HMAC函数生成一个交易对称密钥(KTx))KTx= HMAC(Kchain, N)。 对于KTx,客户端生成两个AES密钥: KTxCID当作HMAC(KTx, c1), KTxP 当作 HMAC(KTx, c2)) 分别加密链码名称或标识CID和代码(或payload)P. c1, c2 是公共常量。nonce,加密的链码ID(ECID)和加密的Payload(EP)被添加到交易Tx结构中,即最终签名和认证的。 下面的图显示了如何产生用于客户端的事务的加密密钥。这张图中的剪头表示HMAC的应用,源由密钥锁定和使用在箭头中的数量作为参数。部署/调用交易的密钥键分别用d/I表示。
为了验证客户端提交到区块链的保密交易Tx,验证实体首先通过和之前一样的Kchain和Tx.Nonce再生成KTxCID和KTxP来解密ECID和EP。一旦链码和Payload被恢复就可以处理交易了。
当V验证一个机密事务,相应的链码可以访问和修改链码的状态。V保持链码的状态加密。为了做到这一点,V生成如上图所示的对称密钥 。让iTX是一个之前由保密交易dTx部署的保密的交易调用一个函数(注意iTx可以是dTx本身)在这种情况下,例如,dTx具有初始化链码状态的设置函数。然后V像下面一样生成两个对称密钥KIV和Kstate:
为了加密状态变量S,验证器首先生成IV像 HMAC(KIV, crtstate)正确截断,其中 crtstate是计数器值,并在每次同样链码调用时请求状态更新时增加。当链码执行终止是计数器丢弃。IV产生之后,V认证加密(即,GSM模式)S的值连接Nstate(实际上,Nstate只需要认证而不需要加密)。在所得的密文(CT), Nstate和IV被追加。为了解密加密状态CT|| Nstate',验证器首次生成对称密钥KdTX' ,Kstate',然后解密CT。
IV的生成: 任何底层共识算法是不可知的,所有的验证各方需要一种方法以产生相同的确切密文。为了做到这一点,需要验证使用相同的IV。重用具有相同的对称密钥相同的IV完全打破了底层密码的安全性。因此,前面所描述的方法制备。特别是,V首先通过计算HMAC(KdTX, c4 || Nstate )派生的IV生成密钥KIV,其中c4是一个常数,并为(dTx, iTx)保存计数器crtstate初始设置为0。然后,每次必须生成一个新的密文,验证器通过计算HMAC(KIV, crtstate)作为输出生成新的IV,然后为crtstate增加1。
上述密钥层次结构的另一个好处是控制了审计的能力。 例如,当发布Kchain会提供对整个供应链的读取权限,当只为交易的(dTx,iTx)发布Kstate访问只授予由iTx更新的状态,等等
下图展示一个部署和调用交易在目前在代码中的形式。
可以注意到,部署和调用交易由两部分组成:
基本信息部分: 包含交易管理细节,如,把这个交易链接到的(被链接到的),交易的类型(被设置为''deploymTx''或''invocTx''),保密策略实现的版本号,它的创建者标识(由TCert,Cert表达)和一个nonce(主要为了防止重放攻击)
代码信息部分: 包含在链码的源代码的信息。本质上是链码标识符/名称和源代码的部署交易,而对调用链码是是被调用函数名称和它的参数。就像在两张图中展示的代码信息那样他们最终是使用链指定的对称密钥Kchain加密的。