劉 芬, 朱壯友, 許 勇
(1.皖南醫學院弋磯山醫院,安徽 蕪湖 241001;2.樅陽第三中學,安徽 銅陵 246704;3.安徽師范大學 計算機與信息學院,安徽 蕪湖 241002)
隨著醫療信息化的發展,醫院逐步實現了病歷文書電子化。由于電子病歷由各家醫院分別管理和保存,患者獲得本人醫療記錄和看病診斷歷史數據不便捷,可追溯性差,導致數據壟斷問題[1]。國家衛健委發布《關于加強全民健康信息標準化體系建設的意見》,指出要探究如何將區塊鏈應用于醫療領域,加快研究制定醫療健康領域區塊鏈信息服務標準,加強規范引導區塊鏈技術與醫療健康行業的融合應用。區塊鏈是新技術,其在醫療領域的運用可以督促醫生提高電子病歷文書的準確性、規范性和客觀性。利用區塊鏈技術,能夠解決電子病歷管理數據安全、流程管理和司法認證的難題,也讓患者本人成為個人醫療數據的真正掌控者。積極推動整個行業打破信息壁壘,為重構全民健康信息標準化體系提供全新方案。區塊鏈本質上是一個分布式數據庫系統,在促進數據可信共享和隱私保護上具有天然優勢,基于區塊鏈的電子病歷場景融合探索已成為研究熱點。
Azaria等[2]提出一種新的分布式病歷管理系統,通過區塊鏈技術實現了對電子病歷的分布式存儲,但共識算法采用工作量證明(Proof Of Work,POW),所需的算力較大。羅等[3]提出一種基于區塊鏈的電子醫療病歷共享方案,實現了單對授權用戶間的醫療數據安全共享功能,但方案只能實現單對用戶間的數據共享,無法實現一個用戶到多個用戶的數據共享,且方案中的共識算法效率還有待提高。蘇等[4]設計并實現了一套基于聯盟式區塊鏈的區域版式電子病歷管理系統,支持電子病歷可信的長期保存和區域共享。但該系統在共識形成和區塊生成方向仍存在效率不高等問題,系統的整體運行效率偏低。張等[5]提出一種基于聯盟鏈的醫療系統,通過實用拜占庭容錯算法(Practical Byzantine Fault Tolerance,PBFT)[6],保證了系統能夠以很小的算力來實現安全穩定的運行,可以避免醫療數據被篡改和泄露,但存在存儲開銷較大,效率低的缺陷。為此,本文在文獻[5]的基礎上提出了基于區塊鏈的電子病歷數據共享模型,可以保證病歷在安全性的條件下,實現病歷的高效共享。
醫院醫療信息系統包括醫院信息系統(Hospital Information System,HIS)、電子病歷系統(Electronic Medical Record,EMR)、實驗室信息管理系統(Laboratory Information Management System,LIS)、影像歸檔和通信系統(Picture Archiving and Communication Systems,PACS)等多類臨床信息處理系統,是電子病歷的生產系統,以產生、流轉、存儲電子病歷等業務為主。電子病歷是以數字化方式取代傳統手寫紙質病歷,它的內容包括紙質病歷的所有信息,分為門(急)診病歷和住院病歷。電子病歷中記錄了醫囑、檢查結果、檢驗結果、治療記錄、病程記錄等信息,包括入院記錄、住院病案首頁、病程記錄、護理文書、護理記錄單等。基于區塊鏈的電子病歷數據共享模型將電子病歷系統與區塊鏈中各功能組件集成,以接口調用的方式實現醫院電子病歷的上傳,技術架構如圖1所示。

圖1 模型技術架構圖
其中,業務層是各家醫院獨立運行的電子病歷系統,存儲患者在醫院產生的各種醫療信息。服務層主要以區塊鏈為載體來實現,通過接口調用的方式實現電子病歷系統與區塊鏈系統數據的傳輸。數據層定義節點如何存儲鏈上的數據,本模型采用“鏈上哈希,鏈下存儲”的方式存儲數據[7-8],各家醫院設立本地關系型數據庫,存儲鏈下數據。醫院間電子病歷系統存在格式無法兼容的問題,數據層定義了病歷通用格式,實現更快的數據傳輸。應用層定義本模型對外提供的統一界面,分為兩種客戶端,分別為醫院級客戶端和普通級客戶端。醫院病案科通過醫院級客戶端,可以實現對病歷的上傳與下載。病歷上傳需要按照統一格式進行上傳,上傳后將進行病歷共識,共識通過的病歷將寫入賬本,并將病歷信息存入醫院本地關系型數據庫。醫院醫護人員通過普通級客戶端,可以實現對病歷的下載。由于上鏈的病歷不可以進行更改[9],若發生醫療糾紛可以對病歷進行追溯,追溯病歷的來源。患者就診時若需要調取本人在其他醫院的就診病歷,醫生可以在患者授權的情況下通過普通級客戶端對歷史病歷進行下載調閱,客戶端界面如圖2所示。系統管理員通過服務端,可以監測區塊鏈情況,并對用戶進行管理,服務端界面如圖3所示。

圖2 病歷客戶端界面

圖3 病歷服務端界面
本文方案的網絡模型由多個區塊鏈節點組成,各家醫院作為區塊鏈上的節點,每個節點都保存著相同的副本,且各個節點間通過P2P網絡進行交互,最終形成一個完整的區塊鏈網絡系統。P2P網絡具有去中心化、可擴展性、健壯性以及負載均衡等特點,各個節點間交互運作、協同處理,每個節點在對外提供服務的同時也使用網絡中其他節點所提供的服務。當某一個區塊鏈節點產生新的區塊時,會通過廣播的方式告訴其他節點,其他節點通過網絡接收到該區塊信息時,會對這個區塊信息進行驗證,當有一定數量的節點都驗證通過后,各個節點會把該區塊更新到各自現有的區塊鏈上,并將患者的病歷信息存儲在醫院本地的關系型數據庫中。最終使得整個區塊鏈網絡中的各個節點信息保持一致,網絡模型如圖4所示。

圖4 網絡模型示意圖
患者在醫院辦理財務出院,醫院病案科將電子病歷進行歸檔,并上傳至區塊鏈。每個醫院病案科的賬號(公鑰)是公開的,并有一個私鑰是保密的,醫院病案科的賬號作為醫院對外的統一賬號,簡稱為醫院賬號,負責病歷的上傳。其中公鑰和私鑰是通過橢圓曲線加密算法(Ellipse Curve Cryptography,ECC)生成,公鑰作為賬號(即賬戶的唯一標識符)使用。ECC是一種公鑰加密技術,基于橢圓曲線理論通過橢圓曲線方程式的性質產生密鑰。具有計算量小、處理速度快、占用較少的存儲空間和傳輸帶寬等優點。本模型選定一條橢圓曲線Ep(a,b),滿足如下公式:
y2=x3+ax+b(modp)
4a3+27b2≠0 (modp)
其中,x,y∈[0,p-1],p為質數,a、b是小于p的非負整數。選取橢圓曲線Ep(a,b)上一點G作為基點(base point),考慮K=kG,由橢圓曲線阿貝爾(Abel)加法群性質可知,點K也在橢圓曲線Ep(a,b)上。每個醫院選擇一個小于n的整數k作為私有密鑰(private key),n為G的階(nG=O∞)。根據K=kG生成K,作為公開密鑰(public key)。ECC加密算法的數學依據是給定k和G,根據加法法則計算K很容易。但反過來,給定K和G求k就非常困難。醫院作為區塊鏈上的節點,將產生區塊并廣播,同時每個節點都部署redis服務器,用于緩存數據。
文獻[6]提出PBFT共識算法,當失效節點數為1,總共節點數為 4時,算法流程如圖5所示。C代表客戶端,0,1,2,3分別代表節點的編號,其中0是主節點,打叉的3代表失效節點。算法的核心分為三個階段分別是預準備階段、準備階段和提交階段。

圖5 PBFT算法流程示意圖
預準備階段,主節點組裝預準備消息,同時把客戶端請求附加在其后:<
準備階段,副本節點會組裝并廣播準備消息給其他節點,同時把預準備和準備消息寫入到本地消息日志中。準備消息格式如下:
提交階段,節點i向其他節點廣播確認消息:
PBFT共識算法無需挖礦,節點所需計算成本較低。但由于要保證各個節點間的頻繁通信,所以節點數不能太多。并且無法防御一個惡意用戶用多個賬戶來進行共識的造假行為,即女巫攻擊。
本文方案對PBFT算法進行改進,得出改進的實用拜占庭容錯算法(Improved Practical Byzantine Fault Tolerance,IPBFT),降低了節點間的通信量,并且有效地提高了安全性。節點采用IPBFT算法對產生的新區塊進行共識。
算法1:IPBFT算法
算法的主要流程分為四步:
a)構造加權投票系統
由n個投票人的集合{A,B,C,…}及他們的投票權重(均為正數)w1,w2,…,wn構成加權投票系統S,用S=[q;w1,w2,…,wn]表示,其中q稱為定額,若記w=w1+w2+…+wn,一般假定w/2 在區塊鏈上維持一個滑動窗口,選取窗口內區塊的產生節點作為選舉團成員對新區塊進行投票,選舉團成員的票數是在滑動窗口內該節點相應的出塊數,如圖6所示。 圖6 共識協議示意圖 b)對病歷的來源進行驗證 產生新區塊的節點(醫院A)向選舉團成員廣播信息,選舉團成員對區塊的來源進行驗證,驗證過程如下。醫院A對病歷進行散列運算后,生成病歷散列H,并用私鑰對病歷散列H進行簽名。將生成后的簽名與患者的電子病歷一起廣播給選舉團成員節點。收到病歷的節點(醫院B)對病歷進行鑒別,鑒別所收到的病歷的確是病歷的發送者所發送的,而不是其他人偽造的或篡改的。基于區塊鏈的電子病歷數據共享模型中,醫院的賬號向全網公布,而確認醫院是賬號擁有者的唯一辦法就是看醫院有沒有賬號對應的私鑰。醫院上傳的電子病歷記錄,只有當上傳病歷的醫院簽名是有效的,病歷才是有效的,病歷鑒別過程如圖7所示。 圖7 病歷鑒別示意圖 c)核實簽名并統計票數 醫院A將病歷X經過散列函數運算后得出很短的病歷散列H,然后用自己的私鑰對病歷散列H進行D(解密)運算,即進行數字簽名。得出已簽名的散列D(H)后,并將其追加在病歷X后面組成擴展的病歷發送給醫院B,其中散列D(H)稱為病歷鑒別碼(Medical Record Authentication Code,MAC)。同時,醫院A用三重DES(3DES)對病歷X進行加密,并將醫院賬號、患者身份證號碼、MAC和加密的病歷在非關系型數據庫系統redis中進行緩存。醫院B收到擴展的病歷后首先把MAC和病歷X分離,然后用醫院A的公鑰對MAC進行E(加密)運算,得出病歷散列H,并對病歷X進行散列函數運算,看是否能夠得出同樣的病歷散列H。如一樣,就能以極高的概率斷定收到的病歷是醫院A上傳的,否則就不是。若醫院B證明病歷X確實是醫院A上傳的,則將病歷散列H進行簽名后返回給醫院A作為投票,醫院A收到簽名后,進行核實簽名并統計票數,如圖8所示。 圖8 病歷上傳方核實簽名示意圖 d)選舉團成員廣播區塊 若票數大于總票數的2/3,則向選舉團成員廣播成員簽名,證明新病歷已經被選舉團接收并驗證。醫院A將redis中的緩存數據取出存儲在醫院本地關系型數據庫中,并將產生的新區塊和redis中的緩存數據廣播給選舉團成員,選舉團成員接收到廣播信息后,將收到的新區塊加入區塊鏈中,并將收到的緩存數據存入醫院本地關系型數據庫。選舉團成員廣播信息給相鄰節點,至此,所有節點對該區塊達成確定性共識,將新區塊加入各自區塊鏈,并將收到的緩存數據存儲在醫院本地關系型數據庫中。醫院A清除緩存數據,區塊鏈上的滑動窗口向前滑動,等待進行下一次共識。 通過病歷共識,各節點已將產生新區塊的醫院賬號、患者身份證號碼、病歷鑒別碼MAC和加密的病歷寫入本地關系型數據庫,鏈上各家醫院本地關系型數據庫存儲的內容是一致的,若同一患者在不同醫院就診,本地數據庫將存儲該患者的多條記錄。患者病歷信息表如表1所示。 表1 患者病歷信息表 圖9 病歷加密示意圖 圖10 病歷解密示意圖 本文方案任一節點的區塊結構由區塊頭和區塊體兩部分組成,區塊頭中包括當前區塊頭hash值、上一區塊頭hash值、Merkle樹根和時間戳等字段。區塊通過存儲上一區塊的哈希值和當前區塊哈希值,可實現鏈上數據的可信追溯。修改節點任一區塊的數據將導致其哈希無效,從而引起斷鏈[10]。區塊體的內容以Merkle樹[11]結構存儲,樹的葉子節點存儲經過驗證的病歷鑒別碼MAC和所有節點的賬號,非葉子節點存儲的是其所有孩子節點的哈希值。最終生成的Merkle樹的根作為摘要被記錄在區塊頭部中,便于區塊的驗證和查找,病歷被篡改可通過區塊頭存儲的Merkle根進行驗證[12-13],區塊結構示意圖如圖11所示。 圖11 區塊結構示意圖 若發生醫療糾紛,可以通過患者身份證號碼查詢醫院本地關系型數據庫中患者所有的電子病歷。通過患者身份證號碼和上傳該病歷的醫院賬號對加密的病歷進行解密,找出有醫療糾紛的病歷、相應病歷鑒別碼MAC和醫院賬號。在區塊鏈中通過醫院本地關系型數據庫返回的病歷鑒別碼MAC查找區塊,如方法1、方法2所示。若定位到指定區塊,則核實該區塊數據部分存儲的所有醫院賬號是否包含醫院本地關系型數據庫返回的醫院賬號。若能夠定位到區塊并核實醫院賬號,則能確定該病歷的上傳方,進而明確責任主體。否則說明該醫院本地關系型數據庫數據被人為進行了修改,不具有參考性,可以在其他就診醫院進行病歷追溯。病歷追溯流程圖如圖12所示。 圖12 病歷追溯流程圖 方法1:先序遍歷Merkle樹,比對病歷鑒別碼MAC boolean preorderTraversalLeaves(MerkleTree MT,MAC mac){ if(MT){ if(MT->left==null && MT->right==null){ if(MT->data==mac)return true; } preorderTraversalLeaves(MT->left,mac); preorderTraversalLeaves(MT->right,mac); } return false; } 方法2:通過MAC查找區塊 Block searchBlockByMAC(Block block,MAC mac){ MerkleTree MT=block->MerkleTree; boolean flag=preorderTraversalLeaves(MT,mac); if(flag)return block; else return null; } 定義1:PBFT共識算法,在包含3f+1個節點的系統中至多存在f個不可信節點(惡意節點),當有2f+1個節點對某個消息達成一致,就能保證整個系統達成一致。 證明:某一時刻,可信節點分成兩部分:f個可信節點支持消息a,記為set(a,f),f個可信節點支持消息b,記為set(b,f)。f個不可信節點對支持消息a的可信節點說他們支持消息a,對支持消息b的可信節點說他們支持b。此時在set(a,f)中的節點看來,對于a消息有2f票,在set(b,f)中的節點看來,對于b消息有2f票,那么當剩下的1個可信節點表態之后,就會使得a消息和b消息一個成為多數派而另一個成為少數派,即消息a獲得2f+1個贊同、消息b獲得2f個贊同或者反之。根據少數服從多數的原則,系統達成共識。換句話說,對于至多存在f個不可信節點的系統中,如果有3f+1個節點時,無論f個不可信節點如何進行干擾,都會使得系統中大部分的可信節點達成共識。 定義2:IPBFT共識算法,在包含3f+1個節點的系統中,當有m個節點對某個消息達成一致,就能保證整個系統達成一致,其中m 證明:對于有n個投票人的加權投票系統S,他的獲勝聯盟集為W,對于W中的每個獲勝聯盟,檢查每位投票人是否是決定者,即這個聯盟是否由于他的加入才獲勝。將每位投票人在W中成為決定者的次數η歸一化,定義為他們在投票系統中的權利指標,記作β=(β1,β2,…,βn)。具有如下性質,若權重wi>wj,則βi≥βj。系統投票權重wi選取投票節點最近的出塊數,故可信節點的權利指標高于不可信節點。在包含3f+1個節點的系統中,選取滑動窗口大小為f,投票節點個數為n,滿足n 由定義1和定義2可知,PBFT算法可以容忍小于1/3個無效或者惡意節點,本文方案在病歷共識過程中采用IPBFT共識算法,可以容忍大于2/3個無效或者惡意節點,有效地抵御了節點間的欺騙攻擊、合謀攻擊和女巫攻擊。且本文方案區塊鏈上僅存儲醫院對病歷散列的簽名,即病歷鑒別碼MAC,網絡攻擊者無法通過攻擊網絡上的節點獲得患者的隱私數據,可以有效地抵御截獲攻擊。通過數字簽名,區塊鏈上的節點能夠確信該病歷的確是產生新區塊的節點發送的,并且沒有被篡改過,產生新區塊的節點也無法抵賴對該病歷的簽名,可以有效地抵御篡改攻擊。患者病歷通過3DES加密后在網絡中傳輸,可以避免中間人攻擊。區塊頭中的時間戳字段記錄了區塊產生的近似時間,可以防止入侵者的重放攻擊。醫療數據備份存儲在多個醫院的本地關系型數據庫中,降低了數據遺失的可能性。 醫院使用的信息系統不盡相同,導致醫院間無法共享信息,患者在不同醫院就診可能要重做相同的檢查。本模型采用“鏈上哈希,鏈下存儲”的方式存儲數據,患者可以攜帶身份證,在診室通過讀卡器讀取身份證號碼,檢索醫院本地的關系型數據庫,可以獲得患者在不同醫院的就診病歷。確保患者醫療信息機密性的條件下,實現區域醫療信息一體化。由于區塊鏈的結構特點,并結合醫院本地關系型數據庫存儲的患者病歷信息,可以實現病歷的可追溯性。 將本文方案與文獻[2]和文獻[5]提出的方案,從方案所采用的共識算法、算力大小、區塊鏈類型和存儲開銷等方面進行對比,如表2所示。 由表2可知,本文方案在病歷鑒別階段采用IPBFT共識算法對產生的新區塊進行共識,通過選舉團投票的方式,不需要所有節點都對病歷進行鑒別,所需的算力較小,避免了大量的計算。由于區塊鏈存儲數據能力有限,本模型采用“鏈上哈希,鏈下存儲”的方式存儲數據,在鏈上只存儲病歷鑒別碼MAC,患者病歷信息則存儲在鏈下醫院的本地關系型數據庫中。并且產生新區塊的節點在redis中通過鍵值對的方式對數據進行緩存,可以實現高效的存取。對三種共識算法進行實驗,通過配置不同的節點個數,得出算法運行時的CPU占用率,如圖13所示。 表2 不同方案對比表 圖13 共識算法的CPU占用率 實驗結果表明,隨著節點個數的增加IPBFT共識算法的CPU占用率低于PBFT共識算法和POW共識算法。PBFT共識算法由于每個副本節點都需要和其它節點進行P2P的共識同步,在較少節點的情況下可以有不錯的性能,但是隨著節點個數的增加,算法性能會下降的很快。POW共識算法是通過前一個區塊的哈希值和隨機值來計算下一個區塊的哈希值,要得到合理的區塊哈希值需要經過大量的計算,將占用較多的CPU資源。 將傳統的客戶端/服務器方式下,服務器節點給所有客戶端節點分發文件所需時間Tcs與本文方案中各個節點將病歷文件封裝在區塊中通過P2P網絡進行文件分發所需時間TP2P進行對比。假設有N臺主機節點要從互聯網上的服務器節點下載一個長度為F的大文件,服務器的上傳速率記為us,主機節點與互聯網連接的鏈路的上傳速率和下載速率分別為ui和di,如圖14所示。 圖14 文件分發示意圖 N臺主機節點共需要從服務器節點得到的數據總量是NF,如果服務器節點能夠不停地以其上傳速率us向各主機傳送數據,一直到各主機都收到文件F,時間為NF/us。由此可見,服務器給所有主機分發完畢的時間Tcs≥NF/us。如果N臺主機都以各自的下載速率不停地下載文件F,那么下載速率最慢的主機(設其下載速率為dmin)的下載文件時間為F/dmin。由此可得出所有主機都下載完文件F的時間下限是 (1) 由公式(1)可知,若括號中的第一項遠大于第二項,則Tcs近似與主機數N成正比。 本文方案在病歷共識通過后,選舉團成員通過P2P方式將文件廣播給相鄰節點。在P2P方式下,每個節點在接收文件的同時,還利用自己的上傳能力向其它節點傳送文件。在文件分發開始時只有選舉團成員節點有文件F,選舉團成員節點必須把文件F的每一個比特通過接入鏈路傳送到互聯網(至少要傳送一次),得出TP2P≥F/ui。下載速率最慢的節點(設其下載速率為dmin)下載文件的時間是F/dmin,得出TP2P≥F/dmin。整個系統中所有節點的上傳速率之和是uT=u1+u2+…+uN,得出TP2P≥NF/uT。這樣,我們得出在P2P方式下所有主機都下載完文件F的時間下限是 (2) 由公式(2)可知,當對等方的數目N非常大,在公式括號中的最后一項的值將遠大于前兩項的值,這樣TP2P值的下限就近似為NF/uT。對比公式(1)和公式(2)可知,本文方案采用P2P文件分發方式,效率高于傳統的客戶端/服務器方式。 本文提出了基于區塊鏈的電子病歷數據共享模型,醫院將患者病歷數據上傳時,通過病歷共識,可以鑒別病歷的有效性和真實性。鏈上只存儲病歷鑒別碼MAC,患者的病歷通過加密的方式存儲在鏈下各醫院的本地關系型數據庫中,實現了病歷存儲的高效性和安全性。由于區塊鏈的結構特征,保證了病歷的可追溯性。本模型可以保證病歷的真實性、安全性、不可篡改以及透明性。在區塊鏈上,數據要經過多個驗證節點的共同驗證,經過共識算法對該項數據的真實性形成共識之后,才能寫入區塊鏈[14]。在驗證節點具備足夠可信性和驗證節點之間不會合謀取利的前提下,區塊鏈的寫入機制能實現信息的發布保真。本模型在提升醫療質量和效率的同時,進一步保護患者隱私,增強患者使用醫療數據的自主性,推動實現居民醫療信息的共享和醫療的去中心化。


1.2 病歷存儲





1.3 病歷追溯


2 性能分析
2.1 安全性
2.2 可共享性與可追溯性
2.3 計算開銷與存儲開銷


2.4 文件分發效率

3 總結