1. 程式人生 > >BlockChain技術系列(四)- fabric安全介紹

BlockChain技術系列(四)- fabric安全介紹

這一節將討論下面的圖所展示的設定描述。特別的,系統是由下面這些實體構成的:成員管理基礎架構,如從一個實體集合中區分出不同使用者身份的職責(使用系統中任意形式的標識,如:信用卡,身份證),為這個使用者註冊開戶,並生成必要的證書以便通過fabric成功的建立交易,部署或呼叫鏈碼。

figure-architecture

  • Peers, 它們被分為驗證 peer 和非驗證 peer。驗證 peer(也被稱為驗證器)是為了規範並處理(有效性檢查,執行並新增到區塊鏈中)使用者訊息(交易)提交到網路上。非驗證 peer(也被稱為 peer)代表使用者接受使用者交易,並通過一些基本的有效性檢查,然後把交易傳送到它們附近的驗證 peer。peer 維護一個最新的區塊鏈副本,只是為了做驗證,而不會執行交易(處理過程也被稱為交易驗證
    )。
  • 註冊到我們的成員服務管理系統的終端使用者是在獲取被系統認定的身份的所有權之後,並將獲取到的證書安裝到客戶端軟體後,提交交易到系統。
  • 客戶端軟體,為了之後能完成註冊到我們成員服務和提交交易到系統所需要安裝在客戶端的軟體
  • 線上錢包,使用者信任的用來維護他們證書的實體,並獨自根據使用者的請求向網路提交交易。線上錢包配置在他們自己的客戶端軟體中。這個軟體通常是輕量級的,它只需有對自己和自己的錢包的請求做授權。也有 peer 為一些使用者扮演線上錢包的角色,在接下來的會話中,對線上錢包做了詳細區分。

希望使用fabric的使用者,通過提供之前所討論的身份所有權,在成員管理系統中開立一個賬戶,新的鏈碼被鏈碼建立者(開發)以開發者的形式通過客戶端軟體部署交易的手段,公佈到區塊鏈網路中。這樣的交易是第一次被 peer 或驗證器接收到,並流傳到整個驗證器網路中,這個交易被區塊鏈網路執行並找到自己的位置。使用者同樣可以通過呼叫交易呼叫一個已經部署了的鏈碼

下一節提供了由商業目標所驅動的安全性需求的摘要。然後我們遊覽一下安全元件和它們的操作,以及如何設計來滿足安全需求。

4.1 商業安全需求

這一節表述的與fabric相關的商業安全需求。 身份和角色管理相結合

為了充分的支援實際業務的需求,有必要超越確保加密連續性來進行演進。一個可工作的B2B系統必須致力於證明/展示身份或其他屬性來開展業務。商業交易和金融機構的消費互動需要明確的對映到賬戶的所有者。商務合同通常需要與特定的機構和/或擁有交易的其他特定性質的各方保證有從屬關係。身份管理是此類系統的關鍵組成部分的兩個原因是問責制和不可陷害的。

問責制意味著系統的使用者,個人或公司,誰的胡作非為都可以追溯到併為自己的行為負責。在很多情況下,B2B系統需要它們的會員使用他們的身份(在某些形式)加入到系統中,以確保問責制的實行。問責制和不可陷害的。都是B2B系統的核心安全需求,並且他們非常相關。B2B系統需要保證系統的誠實使用者不會因為其他使用者的交易而被指控。

此外,一個B2B系統需要具有可再生性和靈活性,以滿足參與者角色和/或從屬關係的改變。

交易隱私.

B2B系統對交易的隱私有著強烈的需求,如:允許系統的終端使用者控制他與環境互動和共享的資訊。例如:一家企業在交易型B2B系統上開展業務,要求它的交易得其他企業不可見,而他的行業合作伙伴無權分享機密資訊。

在fabric中交易隱私是通過下面非授權使用者的兩個屬性來實現的:

  • 交易匿名,交易的所有者隱藏在一個被稱為匿名集的組建中,在fabric中,它是使用者的一個集合。

  • 交易不可關聯,同一使用者的兩個或多個交易不能被關聯起來。

根據上下文,非授權使用者可以是系統以外的任何人,或使用者的子集。

交易隱私與B2B系統的兩個或多個成員之間的保密協議的內容強烈相關。任何授權機制的匿名性和不可關聯性需要在交易時考慮。

通過身份管理協調交易隱私.

就像文件之後描述的那樣,這裡所採用的方法是使戶隱私來協調身份管理,並使有競爭力的機構可以像下面一樣在公共的區塊鏈(用於內部和機構間交易)上快速的交易:

  1. 為交易新增證書來實現“有許可權的”區塊鏈

  2. 使用兩層系統:

    1. 向登記的證頒發機構(CA)註冊來獲得(相對的) 靜態登記證書 (ECerts)

    2. 通過交易CA獲取能如實但偽匿名的代表登記使用者的交易證書(TCerts).

  3. 提供對系統中未授權會員隱藏交易內用的機制

審計支援. 商業系統偶爾會受到稽核。在這種情況下,將給予審計員檢查某些交易,某組交易,系統中某些特定使用者或系統自己的一些操作的手段。因此,任意與商業夥伴通過合同協議進行交易的系統都應該提供這樣的能力。

4.2 使用成員管理的使用者隱私

成員管理服務是由網路上管理使用者身份和隱私的幾個基礎架構來組成的。這些服務驗證使用者的身份,在系統中註冊使用者,併為他/她提供所有作為可用、相容的引數者來建立和/或呼叫交易所需要的證書。公告金鑰體系(Public Key Infrastructure ,PKI)是一個基於不僅對公共網路上交換的資料的加密而且能確認對方身份的公共金鑰加密的。PKI管理金鑰和數字證書的生成,釋出和廢止。數字證書是用來建立使用者證書,並對訊息簽名的。使用證書籤名的訊息保證資訊不被篡改。典型的PKI有一個證書頒發機構(CA),一個登記機構(RA),一個證書資料庫,一個證書的儲存。RA是對使用者進行身份驗證,校驗資料的合法性,提交憑據或其他證據來支援使用者請求一個或多個人反映使用者身份或其他屬性的可信任機構。CA根據RA的建議為特定的使用者發放根CA能直接或分級的認證的數字證書。另外,RA的面向使用者的通訊和盡職調查的責任可以看作CA的一部分。成員服務由下圖展示的實體組成。整套PKI體系的引入加強了B2B系統的強度(超過,如:比特幣)

Figure 1

根證書頒發機構(根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)的結構如下所述:

  • TCertID – 交易證書ID(為了避免通過隱藏的註冊ID發生的意外可關聯性,最好由TCA隨機生成).
  • Hidden Enrollment ID: AES_EncryptK(enrollmentID), 其中金鑰K = [HMAC(Pre-K, TCertID)]256位截斷其中為每個K定義三個不同的金鑰分配方案:(a), (b) and (c)。
  • Hidden Private Keys Extraction: AES_EncryptTCertOwner_EncryptKey(TCertIndex || 已知的填充/校驗檢查向量) 其中||表示連線,其中各個批次具有被加到計數器的唯一(每個批次)的時間戳/隨機偏移量(這個實現中初始化為1)來生成TCertIndex。該計數器可以通過每次增加2來適應TCA生成公鑰,並由這兩種型別的私鑰的TCert所有者來恢復,如簽名金鑰對和金鑰協商金鑰對。
  • Sign Verification Public Key – TCert簽名驗證的公共金鑰。
  • Key Agreement Public Key – TCert金鑰協商的公鑰.
  • Validity period – 該交易證書可用於交易的外/外部簽名的時間視窗。

這裡至少有三種方式來配置考慮了隱藏註冊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 1

Example 2:

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提供信任錨點。

4.2.1 使用者/客戶端註冊過程

下面這個圖高度概括了使用者註冊過程,它具有離線和線上階段。

Registration

離線處理: 在第一步中,每個使用者/非驗證 peer /驗證 peer 有權線上下將較強的識別憑證(身份證明)到匯入到註冊機構(RA)。這需要在頻外給RA提供為使用者建立(儲存)賬號的證據憑證。第二步,RA返回對應的使用者名稱/密碼和信任錨點(這個實現中是TLS-CA Cert)給使用者。如果使用者訪問了本地客戶端,那麼這是客戶端可以以TLS-CA證書作為信任錨點來提供安全保障的一種方法。

線上階段: 第三步,使用者連線客戶端來請求註冊到系統中。使用者傳送它的使用者名稱和密碼給客戶端。客戶端代表使用者傳送請求給PKI框架。第四步,接受包,第五步,包含其中一些對應於由客戶端私有/祕密金鑰的若干證書。一旦客戶端驗證包中所有加密材料是正確/有效的,他就把證書儲存在本地並通知使用者。這時候使用者註冊就完成了。

Figure 4

圖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 的是一樣的。儘管,不同的實現可能使得驗證器直接通過線上過程來註冊。

Figure 5 Figure 6

客戶端: 請求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”)。

4.2.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的改變,增量的差異通過區塊鏈來公佈

4.3 基礎設施層面提供的交易安全

fabric中的交易是通過提交使用者-訊息來引入到總賬中的。就像之前章節討論的那樣,這些資訊具有指定的結構,且允許使用者部署新的鏈碼,呼叫已經存在的鏈碼,或查詢已經存在的鏈碼的狀態。因此交易的方式被規範,公佈和處理在整個系統提供的隱私和安全中起著重要的作用。

一方面我們的成員服務通過檢查交易是由系統的有效使用者建立的來提供驗證交易的手段,為了把使用者身份和交易撇清,但是在特定條件下又需要追蹤特定個體的交易(執法,審計)。也就是說,成員服務提供結合使用者隱私與問責制和不可抵賴性來提供交易認證機制。

另一方面,fabric的成員服務不能單獨提供完整的使用者活動隱私。首先fabric提供完整的隱私保護條款,隱私保護認證機制需要通過交易保密協同。很明顯,如果認為鏈碼的內容可能會洩漏建立者的資訊,那麼這就打破了鏈碼建立者的隱私要求。第一小節討論交易的保密性。

為鏈碼的呼叫強制訪問控制是一個重要的安全要求。fabric暴露給應用程式(例如,鏈碼建立者)這意味著當應用利用fabric的成員服務是,需要應用自己呼叫訪問控制。4.4節詳細闡述了這一點。

重放攻擊是鏈碼安全的另一個重要方面,作為惡意使用者可能複製一個之前的,已經加入到區塊鏈中的交易,並向網路重放它來篡改它的操作。這是第4.3.3節的話題。

本節的其餘部分介紹了基礎設施中的安全機制是如何納入到交易的生命週期中,並分別詳細介紹每一個安全機制。

4.3.1 交易安全的生命週期

交易在客戶端建立。客戶端可以是普通的客戶端,或更專用的應用,即,通過區塊鏈處理(伺服器)或呼叫(客戶端)具體鏈碼的軟體部分。這樣的應用是建立在平臺(客戶端)上的,並在4.4節中詳細介紹。

新鏈碼的開發者可以通過這些fabric的基礎設施來新部署交易:

  • 希望交易符合保密/安全的版本和型別
  • 希望訪問部分鏈碼的使用者有適當的(讀)訪問許可權
    <!-- (read-access code/state/activity, invocation-access) -->
  • 鏈碼規範
  • 程式碼元資料,包含的資訊需要在鏈碼執行時傳遞給它(即,配置引數),和
  • 附加在交易結構上的並只在應用部署鏈碼時使用的交易元資料

具有保密限制的鏈碼的呼叫和查詢交易都是用類似的方式建立。交易者提供需要執行的鏈碼的標識,要呼叫的函式的名稱及其引數。可選的,呼叫者可以傳遞在鏈碼執行的時候所需要提供的程式碼呼叫元資料給交易建立函式。交易元資料是呼叫者的應用程式或呼叫者本身為了它自己的目的所使用的另外一個域。

最後,交易在客戶端,通過它們的建立者的證書籤名,併發送給驗證器網路。 驗證器接受私密交易,並通過下列階段傳遞它們:

  • 預驗證階段,驗證器根據根證書頒發機構來驗證交易證書,驗證交易(靜態的)中包含交易證書籤名,並驗證交易是否為重放(參見,下面關於重放攻擊的詳細資訊) Validators receive the confidential transactions, and pass them through the following phases:
  • 共識階段, 驗證器把這筆交易加入到交易的全序列表中(最終包含在總賬中)
  • 預執行階段, 驗證交易/註冊證書是否在當前的有效期中 解密交易(如果交易是加密的),並驗證交易明文的形式正確(即,符合呼叫訪問控制,包含TCert形式正確) 在當前處理塊的事務中,也執行了簡單的重放攻擊檢查。
  • 執行階段, (解密的) 鏈碼和相關的程式碼元資料被傳遞給容器,並執行。
  • 提交 階段, (解密的)更新的鏈碼的狀態和交易本身被提交到總賬中。

4.3.2 交易保密性

在開發人員的要求下,交易機密性要求鏈碼的原文,即程式碼,描述,是不能被未授權的實體(即,未被開發人員授權的使用者或 peer)訪問或推導(assuming a computational attacker)出來。對於後者,部署呼叫交易的內容始終被隱藏對鏈碼的保密需求是至關重要的。本著同樣的精神,未授權方,不應該能聯絡鏈碼(呼叫交易)與鏈碼本身(部署交易)之間的呼叫關係或他們之間的呼叫。

任何候選的解決方案的附加要求是,滿足並支援底層的成員服務的隱私和安全規定。此外,在fabric中他不應該阻止任何鏈碼函式的呼叫訪問控制,或在應用上實現強制的訪問控制機制(參看4.4小結)。

下面提供了以使用者的粒度來設定的交易機密性機制的規範。最後小結提供了一些如何在驗證器的層次來擴充套件這個功能的方針。當前版本所支援的特性和他的安全條款可以在4.7節中找到。

目標是達到允許任意的子集實體被允許或限制訪問鏈碼的下面所展示的部分: 1. 鏈碼函式頭,即,包含在鏈碼中函式的原型

  1. 鏈碼[呼叫&] 狀態,即, 當一個或多個函式被呼叫時,連續更新的特定鏈碼的狀態。
  2. 所有上面所說的

注意,這樣的設計為應用提供利用fabric的成員管理基礎設施和公鑰基礎設施來建立自己的訪問控制策略和執法機制的能力。

4.3.2.1 針對使用者的保密

為了支援細粒度的保密控制,即,為鏈碼建立者定義的使用者的子集,限制鏈碼的明文讀許可權,一條繫結到單個長週期的加密金鑰對的鏈(PKchain, SKchain)。

儘管這個金鑰對的初始化是通過每條鏈的PKI來儲存和維護的,在之後的版本中,這個限制將會去除。鏈(和相關的金鑰對)可以由任意帶有特定(管理)許可權的使用者通過區塊鏈來觸發(參看4.3.2.2小節)

搭建. 在註冊階段, 使用者獲取(像之前一樣)一張註冊證書,為使用者ui標記為Certui,其中每個驗證器vj獲取的註冊證書標記為Certvj。註冊會給使用者或驗證器發放下面這些證書:

  1. 使用者:

    a. 宣告並授予自己簽名金鑰對(spku, ssku)

    b. 申明並授予他們加密金鑰對(epku, esku),

    c. 獲取鏈PKchain的加密(公共)金鑰

  2. 驗證器:

    a. 宣告並授予他們簽名金鑰對(spkv, sskv)

    b. 申明並授予他們加密金鑰對 (epkv, eskv),

    c. 獲取鏈SKchain的解密(祕密)金鑰

因此,註冊證書包含兩個金鑰對的公共部分:

  • 一個簽名金鑰對[為驗證器標記為(spkvj,sskvj),為使用者標記為(spkui, sskui)] 和
  • 一個加密金鑰對[為驗證器標記為(epkvj,eskvj),為使用者標記為(epkui, eskui)]

鏈,驗證器和使用者註冊公鑰是所有人都可以訪問的。

除了註冊證書,使用者希望通過交易證書的方式匿名的參與到交易中。使用者的簡單交易證書ui被標記為TCertui。交易證書包含的簽名金鑰對的公共部分標記為(tpkui,tskui)。

下面的章節概括性的描述瞭如何以使用者粒度的方式提供訪問控制。

部署交易的結構. 下圖描繪了典型的啟用了保密性的部署交易的結構。

FirstRelease-deploy

注意,部署交易由幾部分組成:

  • 基本資訊部分: 包含交易管理員的詳細資訊,即這個交易對應於哪個鏈(連結的),交易的型別(設定''deplTrans''),實現的保密協議的版本號,建立者的身份(由註冊證書的交易證書來表達),和主要為了防止重放攻擊的Nonce。
  • 程式碼資訊部分: 包含鏈碼的原始碼,函式頭資訊。就像下圖所展示的那樣,有一個對稱金鑰(KC)用於鏈碼的原始碼,另一個對稱金鑰(KH)用於函式原型。鏈碼的建立者會對明文程式碼做簽名,使得信函不能脫離交易,也不能被其他東西替代。
  • 鏈驗證器部分: 為了(i)解密鏈碼的原始碼(KC),(ii)解密函式頭,和(iii)當鏈碼根據(KS)呼叫時加密狀態。尤其是鏈碼的建立者為他部署的鏈碼生產加密金鑰對(PKC, SKC)。它然後使用PKC加密所有與鏈碼相關的金鑰: [(''code'',KC) ,(''headr'',KH),(''code-state'',KS), SigTCertuc(*)]PKc, 並把 where appropriate key material is passed to the In particular, the chain-code creator generates an encryption key-pair for the chain-code it deploys (PKC, SKC). It then uses PKC to encrypt all the keys associated to the chain-code: [(''code'',KC) ,(''headr'',KH),(''code-state'',KS), SigTCertuc(*)]PKc, 私鑰SKC通過鏈指定的公鑰: [(''chaincode'',SKC), SigTCertuc(*)]PKchain. 傳遞給驗證器。
  • 合同使用者部分: 合同使用者的公共金鑰,即具有部分鏈碼讀許可權的使用者,根據他們的訪問許可權加密金鑰:

    1. SKc使得使用者能讀取與這段鏈碼相關的任意資訊(呼叫,狀態,等)

    2. KC使使用者只能讀取合同程式碼

    3. KH 使使用者只能讀取頭資訊

    4. KS使使用者只能讀取與合同相關的狀態

    最後給使用者發放一個合同的公鑰PKc,使得他們可以根據合同加密資訊,從而驗證器(or any in possession of SKc)可以讀取它。每個合同使用者的交易證書被新增到交易中,並跟隨在使用者資訊之後。這可以使得使用者可以很容易的搜尋到有他們參與的交易。注意,為了信函可以在本地不儲存任何狀態的情況下也能通過分析總賬來獲取這筆交易,部署交易也會新增資訊到鏈碼建立者uc

整個交易由鏈碼的建立者的證書籤名,即:有信函決定使用註冊還是交易證書。 兩個值得注意的要點:

  • 交易中的資訊是以加密的方式儲存的,即,code-functions,
  • code-hdrs在使用TCert加密整個交易之前會用想用的TCert簽名,或使用不同的TCert或ECert(如果交易的部署需要帶上使用者的身份。一個繫結到底層交易的載體需要包含在簽名信息中,即,交易的TCert的雜湊是簽名的,因此mix&match攻擊是不可能的。我們在4.4節中詳細討論這樣的攻擊,在這種情況下,攻擊者不能從他看到的交易中分離出對應的密文,即,程式碼資訊,並在另一個交易中使用它。很明顯,這樣會打亂整個系統的操作,鏈碼首先有使用者A建立,現在還屬於惡意使用者B(可能沒有許可權讀取它)
  • 為了給使用者提供交叉驗證的能力,會給他們訪問正確金鑰的許可權,即給其他使用者相同的金鑰,使用金鑰K對交易加密成密文,伴隨著對K的承諾,而這一承諾值開放給所有在合同中有權訪問K的使用者,和鏈驗證器。 <!-- @adecaro: please REVIEW this! --> 在這種情況下,誰有權訪問該金鑰,誰就可以驗證金鑰是否正確傳遞給它。為了避免混亂,這部分在上圖中省略了。

呼叫交易的結構. 下圖結構化描述了,交易呼叫鏈碼會觸發使用使用者指定的引數來執行鏈碼中的函式

FirstRelease-deploy

呼叫交易和部署交易一樣由一個基本資訊, 程式碼資訊鏈驗證器和一個合同使用者,並使用一張呼叫者的交易證書對所有進行簽名。

  • 基本資訊 與部署交易中對應部分遵循相同的結構。唯一的不同是交易型別被設定為''InvocTx'',鏈碼的識別符號或名字是通過鏈指定的加密(公共)金鑰來加密的。

  • 程式碼資訊 部署交易中的對應結構具有相同展現。在部署交易中作為程式碼有效載荷,現在由函式呼叫明細(呼叫函式的名字,對應的引數),由應用提供的程式碼元資料和交易建立者(呼叫者 u)的證書,TCertu。在部署交易的情況下,程式碼有效載荷和是通過呼叫者u的交易證書TCertu簽名的。在部署交易的情況下,程式碼元資料,交易資料是由應用提供來使得信函可以實現他自己的訪問控制機制和角色(詳見4.4節)。

  • 最後,合同使用者和鏈驗證器部分提供金鑰和有效荷載是使用呼叫者的金鑰加密的,並分別鏈加密金鑰。在收到此類交易,驗證器解密 [code-name]PKchain使用鏈指定的金鑰SKchain ,並獲取被呼叫的鏈碼身份。給定的信封,驗證器從本地的獲取鏈碼的解密金鑰SKc,並使用他來解密鏈驗證器的資訊,使用對稱金鑰 KI對呼叫交易的有效荷載加密。給定信函,驗證器解密程式碼資訊,並使用指定的引數和附加的程式碼元資料(參看4.4節的程式碼元資料詳細資訊)執行鏈碼。當鏈碼執行後,鏈碼的狀態可能就更新了。 加密所使用的狀態特定的金鑰Ks在鏈碼部署的時候就定義了。尤其是,在當前版本中Ks 和KiTx被設計成一樣的(參看4.7節)。

查詢交易的結構. 查詢交易和呼叫交易具有同樣的格式。唯一的區別是查詢交易對鏈碼的狀態沒有影響,且不需要在執行完成之後獲取(解密的)並/或更新(加密的)狀態。

4.3.2.2 針對驗證器的保密

這節闡述瞭如何處理當前鏈中的不同(或子集)集合的驗證器下的一些交易的執行。本節中抑制IP限制,將在接下的幾個星期中進行擴充套件。

4.3.3 防重放攻擊

在重放攻擊中,攻擊者“重放”他在網路上“竊聽”或在區塊鏈''看到''的訊息
由於這樣會導致整個驗證實體重做計算密集型的動作(鏈碼呼叫)和/或影響對應的鏈碼的狀態,同時它在攻擊側又只需要很少或沒有資源,所以重放攻擊在這裡是一個比較大的問題。如果交易是一個支付交易,那麼問題就更大了,重放可能會導致在不需要付款人的參與下,多於一次的支付。
當前系統使用以下方式來防止重放攻擊:

  • 在系統中記錄交易的雜湊。這個方法要求驗證器為每個交易維護一個雜湊日誌,釋出到網路上,並把每個新來的交易與本地儲存的交易記錄做對比。很明顯這樣的方法是不能擴充套件到大網路的,也很容易導致驗證器花了比真正做交易還多的時間在檢查交易是不是重放上。
  • 利用每個使用者身份維護的狀態(Ethereum).Ethereum儲存一些狀態,即,對每個身份/偽匿名維護他們自己的計數器(初始化為1)。每次使用者使用他的身份/偽匿名傳送交易是,他都把他的本地計數器加一,並把結果加入到交易中。交易隨後使用使用者的身份簽名,併發送到網路上。當收到交易時,驗證器檢查計數器並與本地儲存的做比較;如果值是一樣的,那就增加這個身份在本地的計數器,並接受交易。否則把交易當作無效或重放的而拒絕掉。儘管這樣的方法在有限個使用者身份/偽匿名(即,不太多)下工作良好。它最終在使用者每次交易都使用不同的標識(交易證書),使用者的偽匿名與交易數量成正比時無法擴充套件。

其他資產管理系統,即比特幣,雖然沒有直接處理重放攻擊,但它防止了重放。在管理(數字)資產的系統中,狀態是基於每個資產來維護的,即,驗證器只儲存誰擁有什麼的記錄。因為交易的重放根據協議(因為只能由資產/硬幣舊的所有者衍生出來)可以直接認為無效的,所以防重放攻擊是這種方式的直接結果。儘管這合適資產管理系統,但是這並不表示在更一般的資產管理中需要比特幣系統。

在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更新他們的資料庫。

    儲存開銷:

    1. 在使用者側:只有最近使用的nonce

    2. 在驗證器側: O(n), 其中n是使用者的數量

  • 使用者使用交易證書提交的交易需要包含一個隨機的nonce,這樣就保證兩個交易不會產生同樣的雜湊。如果交易證書沒有過期的話,驗證器就向本地資料庫儲存這筆交易的雜湊。為了防止儲存大量的雜湊,交易證書的有效期被利用。特別是驗證器為當前或未來有效週期來維護一個接受交易雜湊的更新記錄。

    儲存開銷 (這裡隻影響驗證器): O(m), 其中m近似於有效期內的交易和對應的有效標識的數量(見下方)

4.4 應用的訪問控制功能

應用是抱在區塊鏈客戶端軟體上的一個具有特定功能的軟體。如餐桌預訂。應用軟體有一個版本開發商,使後者可以生成和管理一些這個應用所服務的行業所需要的鏈碼,而且,客戶端版本可以允許應用的終端使用者呼叫這些鏈碼。應用可以選擇是否對終端使用者遮蔽區塊鏈。

本節介紹應用中如何使用鏈碼來實現自己的訪問控制策略,並提供如何使用成員服務來達到相同的目的。

這個報告可以根據應用分為呼叫訪問控制,和讀取訪問控制。

4.4.1 呼叫訪問控制

為了允許應用在應用層安全的實現自己的訪問問控制,fabric需要提供特定的支援。在下面的章節中,我們詳細的說明的fabric為了達到這個目的而給應用提供的工具,併為應用如何來使用它們使得後者能安全的執行訪問控制提供方針。

來自基礎設施的支援. 把鏈碼的建立者標記為 uc,為了安全的實現應用層自己的呼叫訪問控制,fabric必須需要提供特定的支援。
更具體的,fabric層提供下面的訪問能力:

  1. 客戶端-應用可以請求fabric使用指定的客戶端擁有的交易證書或註冊證書來簽名和驗證任何訊息; 這是由Certificate Handler interface來處理的。

  2. 客戶端-應用可以請求fabric一個繫結將身份驗證資料繫結到底層的交易傳輸的應用程式;這是由Certificate Handler interface來處理的。

  3. 為了支援交易格式,允許指定被傳遞給鏈碼在部署和呼叫時間的應用的元資料;後者被標記為程式碼元資料。

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)

}

為了向鏈碼呼叫控制提供應用級