楊武文,馬玉鵬,王 軼*,趙 凡,王保全
(1.中國科學院 新疆理化技術研究所,新疆 烏魯木齊 830011;2.中國科學院大學,北京 100049;3.新疆理化技術研究所 新疆民族語音語言信息處理實驗室,新疆 烏魯木齊 830011)
隨著信息技術的普及應用,電子文件在人們生產生活中必不可少。協同工作、遠程辦公、知識傳播等眾多場景都對文件的網絡存儲和共享提出了強烈需求,各類網盤類文件共享產品隨之產生并成為人們日常生活學習工作中的重要工具。
傳統的網絡文件存儲與共享系統大多采用中心化服務方式,由第三方平臺提供文件存儲與共享服務。雖然已有較多成熟的產品并被廣泛使用,但在數據安全方面仍存在一些問題。一方面,將個人數據交予第三方機構集中式存儲,面臨數據泄露和被濫用的風險。另一方面,文件資源在共享過程中不易受控,即使通過日志等方式記錄共享過程,仍存在中心節點作惡或日志被篡改的風險,導致一些敏感的資源只能在專網或局域網內傳輸共享,應用場景受限。另有部分依托于點對點(Peer-to-Peer,P2P)去中心化網絡的文件共享方式,在數據安全性方面并無改善,且存在穩定性差、難以保證持久化存儲等問題,無法大規模應用。
區塊鏈技術有著不可篡改、可追溯、去中心化[1]等特點,已經在金融[2]、供應鏈[3-5]、多媒體[6-7]、醫療[8-9]等領域得到了廣泛的應用。利用區塊鏈的特性,將區塊鏈技術應用到文件共享系統中,可以有效改善傳統文件共享系統中所面臨的一系列問題:區塊鏈的防篡改與可追溯為文件共享記錄追溯提供了可信保障,去中心化可以有效防止中心節點故障。但區塊鏈面對海量數據存在存儲瓶頸,多節點同步的共享賬本將極大地消耗存儲資源。針對這一問題,采用鏈上鏈下混合的存儲架構逐漸成為主流解決方案。
在區塊鏈存儲擴展方面,Ali M[10]提出了一種將云存儲和區塊鏈相結合的方法解決區塊鏈存儲問題,將數據主體儲到云端,數據的索引存儲在區塊鏈,但云端存儲仍存在著信任問題。Saqib Ali等人[11]為Ping ER(Ping End-to-end Reporting)項目設計了一個分布式存儲架構,架構使用分布式哈希表(Distribute Hash Table,DHT)拓展聯盟鏈的存儲,增加了該項目的可持續性。而隨著IPFS[12]的興起,與區塊鏈技術相結合已逐步成為拓展區塊鏈存儲的重要技術手段[13]。Rafi等人[14]利用區塊鏈和IPFS來存儲物聯網(IoT)設備產生的數據,解決了IoT設備數量巨大時數據安全性存儲的問題,但其仍選取采用工作量證明(Proof Of Work,POW)作為共識機制,會造成資源的浪費。
在基于區塊鏈技術的文件存儲共享應用方面,也有研究人員做了大量工作。Muqaddas等人[15]提出了一種基于區塊鏈的數字資產安全數據共享與交付框架,利用激勵機制促進資源擁有者為客戶提供有質量的數據,但框架基于以太坊進行構建,存在使用代價高昂的缺點。譚海波等人[16]針對檔案數據管理中存在的問題,提出了一種基于聯盟鏈和公有鏈的檔案數據保護方法,實現了檔案館聯盟的數字檔案的保護、驗證、恢復與共享,聯盟鏈和以太坊結合,一定程度上減少了系統使用的代價。Khatal[17]提出了一種基于區塊鏈文件共享框架,實現了數據安全共享和版權保護,但其為了實現版權保護,限制了用戶只能用其DApp才能創建和使用文件數據,用戶不能通過該App存儲分享自己現有的文件和下載文件到本地系統使用。他們大多基于以太坊公鏈進行實現,使用代價較為高昂,或文件被限制不能脫離平臺使用。
該文設計并實現了一個基于Fabric的文件存儲共享系統,有如下特點:
(1)把區塊鏈與IPFS結合,拓展了區塊鏈的存儲;結合IPFS的內容尋址特性和加密技術,實現了文件的防篡改、去冗余持久化存儲。
(2)基于屬性的控制策略方便用戶對文件的操作;權限上鏈和基于細粒度的權限控制,實現了文件的受控共享。
(3)系統實現了對操作歷史信息和文件歷史版本的溯源。對相同文件用同一密鑰加密處理,在提高文件在IPFS中的隱私安全的同時,又不產生額外的存儲空間浪費。
超級賬本(Hyperledger)[18]是由Linux基金會創建和管理的一個開源項目。Hyperledger Fabric是一個開源企業級許可的分布式賬本框架,用于開發解決方案和應用程序,其模塊化和多功能設計可滿足廣泛的行業用例。Hyperledger Fabric具有良好的性能、可伸縮性和信任水平。Fabric可支持多種鍵值數據庫,如levelDB和CouchDB[19]等,該系統選擇使用CouchDB作為狀態數據庫,以提供豐富的查詢功能。
Fabric中智能合約[20]稱為鏈碼(chaincode),鏈碼用來控制區塊鏈網絡中的不同實體或相關方如何相互交互或交易的業務邏輯。鏈碼是獨立可運行的應用程序,運行在基于Docker[21]的安全容器中。鏈碼支持多種語言進行編寫,如Go、Java、NodeJS等。
IPFS集合BitTorrent、DHT、Git、自驗證文件系統(Self-Certifying File System,SFS)和密碼學等已有技術,提供了一種更加便宜、安全、可快速集成的存儲解決方案。IPFS采用為數據塊內容建立哈希去重的方式存儲數據,相同內容的數據塊具有同樣的哈希,數據的存儲成本將會顯著下降。IPFS分為公有集群和私有集群,具有相同的swarm.key才能加入同一個私有集群里。通過IPFS集群,IPFS以可持續的速率固定數據,并在出現故障時重試固定,保證數據持久化存儲。
如圖1所示,所設計的文件共享系統包括四部分:客戶端、系統服務、Fabric聯盟鏈和IPFS私有集群。

圖1 系統架構
客戶端通過良好的界面交互直接給用戶提供服務,通過系統服務提供的RESTful接口進行訪問;系統服務是一種去中心化應用(DApp),通過調用Fabric- SDK和IPFS API,分別與Fabric系統和IPFS集群進行交互配合,實現用戶管理、權限控制、文件操作和信息溯源等系統功能;Fabric存儲用戶、部分文件和控制策略等信息,提供鏈上數據信息的查詢、更新以及驗證等功能;IPFS私有集群則用來存儲文件原始數據,保證持久化存儲,提供穩定的數據支持。
系統主要鏈碼包括文件管理鏈碼(File Manage Chaincode,FMC)、文件授權鏈碼(File Authority Chaincode,FAC)、身份管理鏈碼(Identity Manage Chaincode,IMC)等,如圖2所示。

圖2 鏈碼架構
FMC用于實現文件的保護、驗證、溯源、下載等業務邏輯,包括文件信息存儲鏈碼(File Information Storage Chaincode,FISC)、文件密鑰管理鏈碼(File Encryption Key Manage Chaincode,FEMC)、操作歷史鏈碼(Operation History Chaincode,OHC)。FISC鏈碼用于存儲文件的關鍵信息,包括文件名、摘要信息、類型、屬性、上傳者、版本等信息,執行文件的上傳、下載、更新、共享等操作;FEMC鏈碼用來管理文件加密密鑰,保持與文件加密前后文件指紋的映射關系;OHC鏈碼用于記錄用戶的操作,記錄了操作目標、操作用戶、目標用戶、操作具體內容等信息。
FAC用來實現對文件的細粒度控制,包括目錄管理鏈碼(Catalog Manage Chaincode,CMC)和用戶權限鏈碼(User Auth Chaincode,UAC)。CMC鏈碼對目錄樹進行管理,包括對目錄的創建、修改和刪除等操作;UAC鏈碼控制用戶對目錄及其包含的文件操作權限。
IMC管理整個鏈中所有用戶的身份信息,包括其通行證書ID、用戶名等對應的信息。
文件共享系統既要能夠實現文件受控共享,又要有良好的操作性,需要有合理的權限控制策略來保證。
4.1.1 基于屬性的文件訪問控制策略
根據文件所需共享范圍的差異,分別對文件賦予不同的屬性。基于屬性差別,通過鏈碼進行預處理規則控制,分別執行不同的共享方式和權限訪問控制策略。
如圖3所示,根據業務需求,給文件賦予public、shared和private三類屬性。基于UAC鏈碼,以文件屬性作為輸入,屬性為public的文件由所有用戶任意訪問,屬性為shared的文件根據權限約束進行更加細粒度的控制訪問,屬性為private的文件則只能由文件擁有者進行操作,其他用戶不可見。

圖3 基于屬性訪問控制
4.1.2 基于合約的細粒度權限控制
針對需要共享的數據資源,執行細粒度的權限控制與驗證,如圖4所示。

圖4 細粒度權限控制示意圖
(1)規約系統的數據集和文件瀏覽、下載、刪除和共享等動作,將每項操作均內化成一個權限點,UAC鏈碼為每一個權限點進行編碼注冊。
(2)將權限點、作用域和用戶之間的關系用數據集上鏈存儲,基于CMC、IMC和UAC鏈碼進行細粒度的控制約束。
(3)權限的驗證以權限控制鏈碼為核心,以用戶操作動作為權限點進行輸入,以用戶和權限點的關聯作為授權條件。
4.1.3 面向層級的權限賦予與驗證
為便于進行批量文件資源的共享管理,以文件夾為對象,采用面向層級的作用域權限管理。
依托于文件夾的層級目錄結構,將作用域的根目錄域用戶進行權限綁定,下級目錄自動繼承相應權限。若需要在整體作用域下對部分文件資源權限進行調整,可以以子目錄方式,新建一個作用域,重新關聯用戶和相應權限點,兄弟節點間權限互不影響。
進行權限驗證時,根據文件資源所在層級位置,進行權限查詢與驗證。驗證流程如算法1所示。
算法1:面向層級權限驗證算法。
輸入(nodeId,userId)
輸出(authCode)
authCode =getAuth(nodeId,userId);//查詢當前節點用戶權限
if authCode exist then //如果權限存在
return authCode;//返回權限碼
else
while(authCode=null and nodeId.father != null)//進入循環
nodeId = nodeId.father;//轉到父節點
authCode = getAuth(nodeId,userId); //查詢父節點權限
end while //退出循環
return authCode;//返回查詢到的權限點
end if
用戶在子目錄權限驗證時,若未查詢到當前目錄用戶對應權限點,則向上遞歸查詢驗證,直到達到邊界條件。
4.2.1 基于IPFS的鏈下存儲擴展
區塊鏈由于全節點備份和只可追加的特性,本身面臨較大的存儲壓力,文件本身并不適合寫入區塊。為了對區塊鏈的存儲進行擴展,把文件內容本身存入鏈下IPFS,將文件的摘要信息和IPFS返回的指紋寫入區塊作為鏈上存儲。鏈上文件存儲結構定義如下:
fileStore={file_id,cid,name,ipfs_hash,size,abstract,version,time,user}
其中,file_id是用戶在當前目錄下首次創建時生成的唯一識別碼(Universally Unique Identifier,UUID),作為文件唯一識別id,也作為查詢鍵值;cid是文件當前所屬文件夾id;name,ipfs_hash,size,abstract,version,time,user分別對應文件名,文件IPFS哈希,大小,摘要信息,版本號,上傳時間,文件擁有者。
4.2.2 基于內容尋址的去冗余存儲和版本追溯
IPFS依據內容尋址,存儲時將文件數據劃分為256K的多個塊,根據塊內容計算hash,組合后再次哈希計算構造出整個文件的地址哈希。兩個相同內容的文件只需要存儲一次,達到去冗余效果。若文件部分變動產生變化僅變動內容所在塊的hash也會同步產生變化,此時文件同步會產生新的hash,如圖5所示。

圖5 IPFS文件更新示意圖
Fabric維護了一個歷史索引數據庫,可以快速實現對區塊鏈賬本歷史數據的查詢。系統調用GetHistoryForKey()接口可查詢鍵值對應的歷史變化記錄。
結合Fabric和IPFS的特性,以文件的file_id為鍵值,在歷史數據庫中檢索ipfs_hash的變動記錄,以及相應的文件修改信息,從IPFS中獲取歷史文件數據,實現了對文件歷史版本的追溯。
4.2.3 文件加密存儲
IPFS是一個內容尋址的開放分布式動態共享網絡,在應用與IPFS進行交互時不可避免地需要進行文件內容hash的明文傳輸,處于集群中的任一節點在獲得文件hash的情況下均能下載文件,這導致一定的文件泄露風險。
針對這一問題,該系統采用加密存儲的方式進一步提升文件的安全性,實現對非法訪問的可見不可讀。其中針對IPFS內容尋址特性,對相同內容的文件采用同一密鑰進行加密,使用FEMC鏈碼對密鑰進行統一管理,避免了存儲冗余。
加密存儲流程為:
(1)計算文件hash,調用FEMC鏈碼判斷系統是否已經存儲過相同文件;
(2)若存在,則調用FISC查詢該文件其相關信息,然后在當前用戶目錄下創建該文件,上傳成功;
(3)若不存在,則需要加密后再進行存儲,將新的密鑰及其對應加密前后的hash信息交由FEMC進行管理。關鍵代碼如下所示。
算法2:文件存儲加密算法。
輸入:(file, userId)
輸出 (status)
fileHash=SHA256(file);//計算文件hash
if fileExist(fileHash) then //如果文件存在
fileInfo = getFileInfo(fileHash)//獲取文件信息
status=createNewFile(fileInfo,fileHash,userId);//在用戶目錄下創建文件
return status;//返回成功創建結果
else
key=randomKey();//產生隨機密鑰
encryptedFile= AESencrypt(file, key)//文件加密得到密文
ipfsHash=ipfs.add(encryptedFile);//上傳至IPFS
keyManage(fileHash,ipfsHash,key); //管理文件hash與密鑰
status=createNewFile(fileInfo, fileHash, user.id) //根據文件信息創建文件
return status;//返回創建成功狀態
end if
用戶下載文件時,系統只會給授權的合法用戶進行下載解密,整個過程用戶本身不能拿到密鑰。非法用戶在使用泄露的IPFS hash下載文件后,并不能解密使用,從而實現了文件的隱私安全保護。
系統實現使用Fabric-2.2.0作為區塊鏈框架,鏈碼開發使用Go語言進行編寫;IPFS則使用go-ipfs v0.8.0客戶端進行本地私有集群模式的搭建;客戶端主要通過angular 8框架、Ant Design框架進行構建;系統服務使用了SpringBoot框架,通過Fabric-SDK-Java調用Fabric鏈碼,通過java-ipfs-api實現了與IPFS的接口調用。在文件加解密部分,為了提高處理速率,采用了加解密速度較快的AES對稱加密算法。
核心功能實現了用戶管理、權限編輯、文件操作和信息溯源等功能。用戶管理主要包括用戶注冊、用戶信息編輯等功能;權限編輯包括了權限的賦予、編輯和申請驗證等功能;文件操作包括了文件的上傳、共享、下載、更新和檢索等常用功能;信息溯源包括了對文件歷史信息等溯源,以及用戶的操作記錄和共享記錄等。
實驗設備為1臺筆記本電腦,配置為16 GB內存,Intel Corei5處理器,兩臺服務器搭載了CentOS 7.9系統,16 GB內存,E5620處理器。使用Fabric自帶的etcdRaft共識協議,共兩個組織,每個組織一個證書頒發機構(Certificate Authority,CA),兩個peer節點,一個排序節點。其中Fabric初始參數配置為:BatchTimeout:2 s,MaxMessageCount:500,Absolute MaxBytes:10 MB,PreferredMaxBytes:2 MB。
系統中對文件的操作以上傳下載的時間開銷最大,主要包含文件到IPFS網絡的上傳下載,文件本身的加解密和相關信息的上鏈存儲三個過程。為了探究各個階段處理性能,以四組不同尺寸大小的文件做上傳下載測試。文件平均尺寸分別為0.5 M,4 M,10 M和80 M,每組50個測試樣例。測試結果取平均值,實驗數據如表1所示。

表1 系統性能測試結果(BatchTimeout=2)
由表1測試結果可以看出,系統總耗時,IPFS耗時和加解密耗時均隨著文件尺寸增大而增大,其中加解密過程所占耗時對于整個文件上傳下載處理速度影響幾乎可以忽略不計。區塊鏈系統交易耗時相對穩定,且上傳交易耗時是下載交易的兩倍,這是由于上傳操作Fabric系統需要處理兩筆數據寫入交易:一筆是創建文件信息,另一筆是文件密鑰的管理。而下載操作,只是調用了查詢交易,沒有賬本數據的寫入操作。

表2 系統性能測試結果(BatchTimeout=0.2)
可以注意到,在文件尺寸較小時,相關信息的上鏈交易是主要的性能瓶頸。分析其原因,主要在于Fabric出塊速度受四個參數共同影響,需滿足任意一個參數才能完成區塊的上鏈寫入。在本實驗中由于測試輸入并發不夠,上鏈信息并不滿足其他參數條件,只能等待時間達到BatchTimeout設定的時間條件才能觸發數據打包,出塊完成交易。針對這一問題,調整Fabric出塊配置參數,將BatchTimeout時間設為0.2 s,其他參數保持不變,驗證交易耗時的提升。實驗結果如表2所示。
可以看出,調整后系統信息上鏈耗時有了明顯的降低,在應用中可以根據實際的并發壓力,調整Fabric的網絡參數以提升系統性能。綜合而言,系統的整體性能可以接受,能夠滿足用戶的實際使用需求。
該系統采用的許可型區塊鏈Fabric,結合IPFS實現文件資源的安全存儲與共享。系統安全性從以下三個方面來保證:
Fabric安全性:利用Fabric認證機制保護,只有經過系統認證的合法用戶才能進入區塊鏈進行操作。區塊鏈節點間通信可以通過TLS來保證傳輸層的安全。Fabric系統會區分參與的節點和應用程序角色,為訪問資源的操作設置嚴格的權限控制。
IPFS安全性:IPFS對數據進行分布式存儲,通過集群可把整個系統存儲統一調度,能夠實現資源自動修復和去冗余,自帶容災備份功能。通過swarm.key組成私有集群,可以與外部數據有效隔離,保證數據僅在IPFS私有集群中流轉。IPFS存儲文件時將文件分割成數據塊存儲,并通過計算數據塊的哈希值來進行唯一標識該文件,只有通過文件的CID才能從IPFS網絡中獲取到該文件。
文件流轉安全:細粒度權限控制鏈碼,可以有效控制文件的合法流轉。隨機生成密鑰對文件進行加密,密鑰與文件本身分別存儲在區塊鏈系統和IPFS中,在整個文件的流轉過程中,密鑰由系統進行管理,其他任何人無權單獨取出密鑰,即使非法用戶通過IPFS集群中節點獲取到了加密文件,也無法獲取文件解密對應的密鑰,從而保證了文件的流轉安全。
通過模擬權限受限用戶,解析客戶端與服務端通信的數據,可以獲得當前用戶可見但無權操作的列表文件對應的CID。對獲取到的CID進行下載驗證,通過文件CID可從IPFS集群中的節點獲取到文件,但由于無法獲取到對應的文件密鑰,無法對獲取到的文件進行解密。因此系統安全性得到保障。
分別用區塊鏈、區塊鏈+IPFS的方式存儲文件,對比兩種方式的單個區塊平均大小和系統整體存儲消耗。測試樣例為四組不同大小的文件,文件平均尺寸分別為0.5 M,1 M,2 M,4 M,每組50個測試樣例進行存儲測試,測試結果如圖6所示。
圖6(a)所示為區塊存儲文件和區塊存儲文件CID兩種方案的單個區塊大小,由于存儲CID時區塊平均大小僅為60 KB,在圖中所占比例太小幾乎不可見。而采用區塊存儲文件時,區塊的平均大小約為所存文件的4.8倍。在存儲超過10 M的文件測試時,會導致區塊鏈系統崩潰,這是由于存儲文件時是作為單筆區塊交易進行,單筆交易數據過大導致系統產生錯誤,所以Fabric中單筆交易數據不能過大。

圖6 存儲性能測試
使用區塊存儲文件時會導致區塊大小尺寸五倍增大,對區塊數據進行了多次測試和解析。區塊在存儲
圖6(b)展示的為不同節點數量存儲相同文件時的系統整體存儲空間消耗,其中IPFS的備份數量設定為3。采用區塊鏈賬本存儲文件導致整個系統的存儲空間消耗極具增大,且隨著節點數量增加線性增長。
綜上所述,該系統所采用的方式具有極大的空間節省性能。
系統利用區塊鏈技術克服了傳統文件存儲共享系統存在的不易溯源和防篡改性差的問題;通過細粒度的權限控制實現了文件受控共享;文件采用先驗證是否存在,然后確定是否加密存儲的方法,在提高隱私安全的同時,沒有帶來額外的空間浪費。通過實驗測試,系統的整體性能可以滿足日常生活需要。在未來工作中,將會探究對已存儲文件的內容進行分布式檢索等功能,探索新的功能和方法,進一步完善系統。