作者:Zhiniang Peng from Qihoo 360 Core Security
來源:360 Technology Blog
在NEO采用dBFT機制實現共識節點之間的“拜占庭容錯”,并在NEO白皮書中描述惡意共識節點小于1/3的時候,該共識機制能夠保證系統的安全性和可用性。我們經過研究發現,目前NEO的dBFT機制僅能保證誠實的共識節點之間達成共識。但共識節點之間不存在分叉,并不意味著全網不會存在分叉。NEO目前對dBFT共識機制的實現還不滿足 f = 「floor (n-1) / 3)」 的拜占庭容錯性質。
NEO dBFT共識機制簡介
NEO區塊鏈是一個分布式的智能合約平臺。NEO實現了一種委托的拜占庭容錯共識算法,它借鑒了一些 PoS 的特點(NEO持有人需要對共識節點進行投票) 利用最小的資源來保障網絡免受拜占庭故障的影響,同時也彌補了 PoS 的一些問題。dBFT對由n個共識節點組成的共識系統,提供 f = 「floor (n-1) / 3)」 的容錯能力,這種容錯能力同時包含安全性和可用性,并適用于任何網絡環境。
NEO dBFT共識機制可以詳細見NEO官方共識機制白皮書:
- http://docs.neo.org/zh-cn/basic/consensus/whitepaper.html (中文版)
- http://docs.neo.org/en-us/basic/consensus/whitepaper.html (英文版)
拜占庭將軍問題和區塊鏈
拜占庭位于如今的土耳其的伊斯坦布爾,是東羅馬帝國的首都。由于當時拜占庭羅馬帝國國土遼闊,為了防御目的,因此每個軍隊都分隔很遠,將軍與將軍之間只能靠信差傳消息。 在戰爭的時候,拜占庭軍隊內所有將軍和副官必需達成一致的共識,決定是否有贏的機會才去攻打敵人的陣營。但是,在軍隊內有可能存有叛徒和敵軍的間諜,左右將軍們的決定又擾亂整體軍隊的秩序。在進行共識時,結果并不代表大多數人的意見。這時候,在已知有成員謀反的情況下,其余忠誠的將軍在不受叛徒的影響下如何達成一致的協議,拜占庭問題就此形成。PBFT算法,是解決拜占庭將軍問題的一個經典算法。
區塊鏈是一種去中心化的分布式賬本系統,它可以用于登記和發行數字化資產、產權憑證、積分等,并以點對點的方式進行轉賬、支付和交易。區塊鏈技術最早是由中本聰在一個密碼學的郵件列表中提出的,也就是比特幣。此后,基于區塊鏈技術的各種應用紛紛出現,比如基于區塊鏈的電子現金系統、基于區塊鏈的股權交易系統、基于區塊鏈的智能合約系統等。區塊鏈系統與傳統的中心化賬本系統相比,具有完全公開、不可篡改、防止多重支付等優點,并且不依賴于任何的可信第三方。然而,和任何分布式系統一樣,區塊鏈系統會面臨網絡延遲、傳輸錯誤、軟件錯誤、安全漏洞、黑客入侵等問題。此外,去中心化的特點決定了此系統的任何一個參與者都不能被信任,可能會出現惡意節點,以及因各方利益不一致導致的數據分歧等問題。為了防范這些潛在的錯誤,區塊鏈系統需要一個高效的共識機制來確保每一個節點都有一個唯一公認的全局賬本。傳統的針對某些特定問題的容錯方法,并不能完全解決分布式系統以及區塊鏈系統的容錯問題,人們需要一種能夠容忍任何種類錯誤的容錯方案。
NEO區塊鏈共識機制細節
采用了拜占庭容錯委托(dBFT)作為共識機制( http://docs.neo.org/en-us/basic/consensus/consensus.html )。全網中的NEO節點分為兩類節點:一類為共識記點,負責和其他共識記點之間進行共識通訊,產生新的區塊;另外一類為普通節點,不參與共識,但能夠驗證和接受新的區塊。共識節點由全網用戶通過投票產生。NEO節點提出dBFT的背后思想是:PBFT算法能夠很好的解決分布式節點的共識問題,但是PBFT共識參與節點數量越大性能就會越低。采用投票選取出相對較小數量的共識節點內部進行PBFT共識生成新區塊,然后將該新區塊發布到全網中達成全網共識。NEO共識節點之間,產生新區塊的正常共識流程如下:
- 開啟共識的節點分為兩大類,非記賬人和記賬人節點,非記賬人的不參與共識,記賬人參與共識流程
- 選擇議長,Neo議長產生機制是根據當前塊高度和記賬人數量做MOD運算得到,議長實際上按順序當選
- 節點初始化,議長為primary節點,議員為backup節點。
- 滿足出塊條件后議長發送PrepareRequest
- 議員收到請求后,驗證通過簽名發送PrepareResponse
- 記賬節點接收到PrepareResponse后,節點保存對方的簽名信息,檢查如果超過三分之二則發送 block
- 節點接收到block,PersistCompleted事件觸發后整體重新初始化,
為了防止惡意的共識節點或議長,保證系統的安全性和可靠性,NEO提出changeview機制進一步增強dBFT的安全性。當節點 i 在經過 2^{v+1}.t 的時間間隔后仍未達成共識,或接收到包含非法交易的提案后,開始進入視圖更換流程:
- 令
k = 1,v_{k} = v + k - 節點
i發出視圖更換請求〈ChangeView, h, v, i, v_{k}〉 - 任意節點收到至少
n-f個來自不同i的相同v_{k}后,視圖更換達成,令v = v_{k}并開始共識; - 如果在經過
2^{v+1}.t的時間間隔后,視圖更換仍未達成,則k遞增并回到第 2 步; NEO共識節點總體流程如圖:

dBFT共識機制問題分析
dBFT的核心思想,是想通過選舉出的共識節點通過pBFT協議達成共識,從而產生全網的共識。這看上去是一個很好的思路,但由于dBFT和pBFT中,共識節點為非共識節點提供服務的模型不一樣。在pBFT中,非共識節點(客戶端節點)需要收到至少f+1個共識節點的相同的執行結果,從而獲得服務結果。而dBFT中,非共識節點需要獲得一個由至少2f+1個共識節點共同簽名的block。dBFT的拜占庭容錯,不能想當然的從pBFT中得出。證明一個共識協議的安全性,需要嚴謹的證明。
在分析網絡協議安全性的一個重要的前提是,網絡是一個復雜的環境,我們不能保證先發去的包一定先到達。這是網絡協議之所以復雜的原因。下面我們給出兩個反例,證明dBFT無法提供 f = 「floor (n-1) / 3)」 的拜占庭容錯。
攻擊案例1:
假設7個節點A1 A2 A3 A4 A5 A6 A7。其中議長A1和A2是惡意節點(小于1/3節點數),同時A1擔任本輪議長。A1生成block1發送PrepareRequest(block1)給A2 A3 A4,同時生成block2發送PrepareRequest(block2)給A5 A6 A7。當大家都收到PrepareRequest消息后。A2 A3 A4會返回PrepareRespone(block1)消息,A5 A6 A7會返回PrepareRespone(block2)消息。此時,Block1和Block2的簽名已經在網絡上公開4個。網絡還未達成共識,還需進一步協商,最終生成的共識區塊未定。但此時惡意節點A2實際上可以產生block2的簽名(他自己手上能有5個block2的簽名),故A2有能力在網絡中產生一個分叉。dBFT在該攻擊案例下,無法實現拜占庭容錯(2個惡意節點)。
攻擊案例2:
假設7個節點A1 A2 A3 A4 A5 A6 A7。 其中A2為惡意節點(只有一個惡意節點)。 假設A1當選本輪議長,由于大量交易處理或其他網絡原因,A1產生了延遲。并在臨界timeout的事件發送一個block1出去。其中 A5 A6 A7 剛剛好在限定時間內收到并完全整個block1驗證,回復了簽名。 A2 A3 A4還沒有收到這個block1。此時,按照dBFT協議,timeout時間到,所有人將要求change view。 剛好,change view的包,比Block1提前到達了A2 A3 A4處。大家達成了change view的共識。然后進行下一個view階段。 如果在此階段,A2 A3 A4收到了block1,但是view和議長已經改變了,他們并不會接受block1。那么大家會進入下一輪,產生block2。 Block2生產過程一切正常,A3 A4 A5 A6 A7幾個誠實的節點達成了共識。 但是此時,A2擁有Block1的5個簽名。它能夠構造Block1. 由此,A2可以在網絡中產生了一個分叉。dBFT在該攻擊案例下,無法實現拜占庭容錯(1個惡意節點)。
NEO當前的對dBTF的實現有所不足的本質原因在于:NEO的dBTF實現試圖用共識節點之間的共識代替全網共識;然而這個假設并不嚴格成立。dBFT僅能保證誠實的共識節點之間產生共識,而誠實的共識節點之間的共識與全網節點之間的共識并沒有嚴格的綁定關系。在上面的例子1中,惡意的出塊節A1 A2點無法影響共識節點之間產生共識Block2,但它能產生區塊Block1從而造成網絡中普通節點的分叉。按NEO目前設計,一旦分叉產生,分叉節點就無法回到NEO網絡了。
問題的影響
在發現問題的當天,我們就將該問題郵件發給NEO創始人Erik Zhang。 Erik也在當天回復說他們已經發現了這個問題,并且在社區內做過相關聲明。之前NEO在github項目上發起了一個Pull Request處理該問題,得到了社區成員的積極響應,為該問題建言獻策,目前問題已經初步解決,正在測試穩定性,具體連接: https://github.com/neo-project/neo/pull/320。
通過對該PR具體討論和實現的研究,我們發現實際上該PR主要是針對NEO當前dBTF中對PBFT的實現不夠完善進行的修復。社區目前的理解是:由于NEO中dBFT缺乏PBFT的commit階段,所以可能因為共識節點之間的網絡延遲或者宕機問題,造成共識節點之間無法達成共識。但即使增加commit過程,也無法防止惡意共識節點構造分叉塊。NEO團隊針對此問題,已經在該PR下提出了新的改進方案,目前NEO社區正在完善之前的PR從而徹底解決該問題。在這次問題的解決過程中我們發現NEO團隊對于安全問題處理專業高效,社區響應熱情及時。360安全團隊會繼續與NEO一起測試、分析并完善相關問題,推動NEO與區塊鏈技術向前發展。
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/708/
暫無評論