為什么比特幣可以防篡改
比特幣(Bitcoin)是一種加密貨幣,也是一種分布式的數(shù)字資產(chǎn),中本聰發(fā)布比特幣到今天已經(jīng)過(guò)去了 10 多年時(shí)間[^1],一些讀者可能接觸過(guò)區(qū)塊鏈技術(shù),甚至投資過(guò)數(shù)字貨幣的資產(chǎn)。今天的區(qū)塊鏈總市值已經(jīng)達(dá)到了 2700 億美金,比特幣的市值也達(dá)到了 1700 億[^2],然而比特幣使用的底層技術(shù)其實(shí)非常簡(jiǎn)單,它只是將這些技術(shù)巧妙地組合起來(lái)。
圖 1 - 比特幣
如果我們對(duì)比特幣等區(qū)塊鏈技術(shù)稍有了解,就會(huì)發(fā)現(xiàn)它是一個(gè)設(shè)計(jì)巧妙的分布式數(shù)據(jù)庫(kù)。作為在公網(wǎng)運(yùn)行的分布式數(shù)據(jù)庫(kù),比特幣和其它區(qū)塊鏈網(wǎng)絡(luò)都會(huì)面對(duì)網(wǎng)絡(luò)中的惡意節(jié)點(diǎn)的攻擊。因?yàn)楸忍貛判枰鎸?duì)復(fù)雜的網(wǎng)絡(luò)環(huán)境以及不可靠的節(jié)點(diǎn),所以它在設(shè)計(jì)和實(shí)現(xiàn)上也做出了應(yīng)對(duì),我們可以看看它是如何組合現(xiàn)有的技術(shù)防止惡意節(jié)點(diǎn)對(duì)交易和賬戶數(shù)據(jù)進(jìn)行篡改的。
比特幣網(wǎng)絡(luò)主要會(huì)通過(guò)以下兩種技術(shù)保證用戶簽發(fā)的交易和歷史上發(fā)生的交易不會(huì)被攻擊者篡改:
- 非對(duì)稱加密可以保證攻擊者無(wú)法偽造賬戶所有者的簽名;
- 共識(shí)算法可以保證網(wǎng)絡(luò)中的歷史交易不會(huì)被攻擊者替換;
非對(duì)稱加密
非對(duì)稱加密算法[^3]是目前廣泛應(yīng)用的加密技術(shù),TLS 證書和電子簽名等場(chǎng)景都使用了非對(duì)稱的加密算法保證安全。非對(duì)稱加密算法同時(shí)包含一個(gè)公鑰(Public Key)和一個(gè)私鑰(Secret Key),使用私鑰加密的數(shù)據(jù)只能用公鑰解密,而使用公鑰解密的數(shù)據(jù)也只能用私鑰解密。
asymmetric-cryptography
圖 2 - 非對(duì)稱加密特性
比特幣使用了非對(duì)稱加密算法保證每一筆交易的安全,網(wǎng)絡(luò)中的每一個(gè)賬戶(地址)都是一對(duì)秘鑰中的公鑰,賬戶的所有者會(huì)持有私鑰,下面就是一對(duì)剛剛生成的比特幣地址和私鑰[^4]:
- Address: 13RTT8MsbAj7o4zL7w4DNNuuwhgGgHqLnK
- Private Key: 469d998dd4db3dfdd411fa56574e52b6be318f993ca696cc5c683c45e8e147eb
需要注意的是,使用網(wǎng)站生成比特幣地址和私鑰是極其危險(xiǎn)的做法,我們并不清楚網(wǎng)站是否會(huì)存儲(chǔ)私鑰,所以建議使用比特幣的客戶端生成公私鑰對(duì)。
任何人通過(guò)上面的地址 13RTT8MsbAj7o4zL7w4DNNuuwhgGgHqLnK 都可以向該賬號(hào)轉(zhuǎn)賬;賬號(hào)的持有者也可以使用私鑰簽名交易向其他地址轉(zhuǎn)賬,當(dāng)我們想要向比特幣網(wǎng)絡(luò)中提交一筆新的交易時(shí),需要先構(gòu)建一個(gè)如下所示的交易結(jié)構(gòu):
- {
- "txid":"5be7a9e47f56c98e5297a44df52da0475f448ece98bb51489103cdf70653092f",
- "hash":"5be7a9e47f56c98e5297a44df52da0475f448ece98bb51489103cdf70653092f",
- "version":1,
- "size":224,
- "vsize":224,
- "locktime":0,
- "vin": [...],
- "vout": [...],
- "hex":"0100000001a90b4101e6cbb75e1ff885b6358264627581e9f96db9ae609acec98d72422067000000006b483045022100c42c89eb2b10aeefe27caea63f562837b20290f0a095bda39bec37f2651af56b02204ee4260e81e31947d9297e7e9e027a231f5a7ae5e21015aabfdbdb9c6bbcc76e0121025e6e9ba5111117d49cfca477b9a0a5fba1dfcd18ef91724bc963f709c52128c4ffffffff02a037a0000000000017a91477df4f8c95e3d35a414d7946362460d3844c2c3187e6f6030b000000001976a914aba7915d5964406e8a02c3202f1f8a4a63e95c1388ac00000000",
- "blockhash":"0000000000000000000c23ca00756364067ce5e815deb5982969df476bfc0b5c",
- "confirmations":5,
- "time":1521981077,
- "blocktime":1521981077
- }
接下來(lái),我們可以使用持有的私鑰對(duì)整個(gè)交易中的全部字段進(jìn)行簽名,然后將簽名與交易打包并發(fā)送到網(wǎng)絡(luò)中等待比特幣網(wǎng)絡(luò)的確認(rèn)就可以了。
在比特幣的所有地址中,35hK24tcLEWcgNA4JxpvbkNkoAcDGqQPsP 地址中目前持有 250,000 多個(gè) Bitcoin[^5],目前的市值大概為 20 億美元。在只知道地址的情況下,我們來(lái)算一下獲取該地址對(duì)應(yīng)的私鑰需要多長(zhǎng)時(shí)間。比特幣的私鑰總共有 256 位,即2256種可能。
目前我們沒有較為快捷的破解手段,只能使用暴力破解計(jì)算私鑰。假設(shè)我們使用 IBM 在 2018 年推出的超級(jí)計(jì)算機(jī) Summit[^6],它能每秒能做1.4*107次浮點(diǎn)數(shù)計(jì)算,假設(shè)該計(jì)算機(jī)可以每秒計(jì)算相同次數(shù)的公私鑰對(duì)(計(jì)算公私鑰對(duì)遠(yuǎn)比一次浮點(diǎn)數(shù)計(jì)算復(fù)雜),想要找到存放 20 億美元資產(chǎn)的地址對(duì)應(yīng)的私鑰需要如下所示的時(shí)間:
我們整個(gè)宇宙的存在時(shí)間也只是破解該私鑰時(shí)間的幾十億分之一,所以在目前的計(jì)算能力沒有革命性突破的前提下,想要通過(guò)暴力破解的方式獲取公鑰對(duì)應(yīng)的私鑰只有理論上的可能性,在實(shí)踐中是完全不可能的[^7]。
共識(shí)算法
MySQL 等數(shù)據(jù)庫(kù)以行為單位存儲(chǔ)數(shù)據(jù),而比特幣這個(gè)分布式數(shù)據(jù)庫(kù)中存儲(chǔ)的基本單位是區(qū)塊,區(qū)塊通過(guò)哈希指針連接就會(huì)構(gòu)成一顆樹,如下圖所示,圖中綠色的最長(zhǎng)鏈就是網(wǎng)絡(luò)的主鏈。
blockchain-and-blocks
圖 3 - 區(qū)塊鏈和主鏈
如何讓網(wǎng)絡(luò)中的所有節(jié)點(diǎn)對(duì)下一個(gè)區(qū)塊中的內(nèi)容達(dá)成共識(shí)是比特幣需要解決的關(guān)鍵問(wèn)題,只有讓節(jié)點(diǎn)對(duì)數(shù)據(jù)達(dá)成一致才會(huì)保證過(guò)去的交易不會(huì)被篡改,但是作為在公網(wǎng)運(yùn)行的分布式數(shù)據(jù)庫(kù),它面對(duì)的場(chǎng)景非常復(fù)雜,需要解決拜占庭將軍問(wèn)題下的分布式一致性問(wèn)題。
拜占庭將軍問(wèn)題是 Leslie Lamport 在 The Byzantine Generals Problem 論文中提出的分布式領(lǐng)域的容錯(cuò)問(wèn)題,它是分布式領(lǐng)域中最復(fù)雜、最嚴(yán)格的容錯(cuò)模型[^8]。在該模型下,系統(tǒng)不會(huì)對(duì)集群中的節(jié)點(diǎn)做任何的限制,它們可以向其他節(jié)點(diǎn)發(fā)送隨機(jī)數(shù)據(jù)、錯(cuò)誤數(shù)據(jù),也可以選擇不響應(yīng)其他節(jié)點(diǎn)的請(qǐng)求,這些無(wú)法預(yù)測(cè)的行為使得容錯(cuò)這一問(wèn)題變得更加復(fù)雜。
拜占庭將軍問(wèn)題描述了一個(gè)如下的場(chǎng)景,有一組將軍分別指揮一部分軍隊(duì),每一個(gè)將軍都不知道其它將軍是否是可靠的,也不知道其他將軍傳遞的信息是否可靠,但是它們需要通過(guò)投票選擇是否要進(jìn)攻或者撤退:
byzantine-generals-problem
圖 4 - 拜占庭將軍問(wèn)題
區(qū)塊鏈技術(shù)使用 共識(shí)算法 和激勵(lì)讓多個(gè)節(jié)點(diǎn)在拜占庭將軍場(chǎng)景下實(shí)現(xiàn)分布式一致性。比特幣使用如下的規(guī)則讓多個(gè)節(jié)點(diǎn)實(shí)現(xiàn)分布式一致性:
- 引入工作量證明 — 讓節(jié)點(diǎn)在提交新的區(qū)塊之前計(jì)算滿足特定條件的哈希,取代傳統(tǒng)分布式一致性算法中,一人一票(或者一節(jié)點(diǎn)一票)的設(shè)定;
- 引入最長(zhǎng)鏈?zhǔn)侵麈湹脑O(shè)定 — 只有主鏈上的交易才被認(rèn)為是合法交易;
- 引入激勵(lì) — 提交區(qū)塊的節(jié)點(diǎn)可以獲得比特幣獎(jiǎng)勵(lì);
通過(guò)以上的規(guī)則,各個(gè)節(jié)點(diǎn)會(huì)在最長(zhǎng)的鏈上計(jì)算哈希,努力提交合法的區(qū)塊。然而一旦節(jié)點(diǎn)中有人掌握了 51% 以上的計(jì)算能力,它能通過(guò)強(qiáng)大的算力改變區(qū)塊鏈的歷史。因?yàn)閰^(qū)塊具有連續(xù)性,所以前一個(gè)區(qū)塊的改變會(huì)使后一個(gè)區(qū)塊計(jì)算的哈希失效,如圖 5 所示,如果攻擊者需要改變主鏈中的倒數(shù)第三個(gè)黃色區(qū)塊,它需要連續(xù)構(gòu)建四個(gè)區(qū)塊才能完成對(duì)歷史的篡改,其他的節(jié)點(diǎn)才會(huì)在這條更長(zhǎng)的鏈上繼續(xù)計(jì)算:
51-percent-attack
圖 5 - 51% 攻擊
使用如下所示的代碼可以計(jì)算在無(wú)限長(zhǎng)的時(shí)間中,攻擊者持有 51% 算力時(shí),改寫歷史 0 ~ 9 個(gè)區(qū)塊的概率[^10]:
- #include <math.h>
- #include <stdio.h>
- double attackerSuccessProbability(double q, int z) {
- double p = 1.0 - q;
- double lambda = z * (q / p);
- double sum = 1.0;
- int i, k;
- for (k = 0; k <= z; k++) {
- double poisson = exp(-lambda);
- for (i = 1; i <= k; i++)
- poisson *= lambda / i;
- sum -= poisson * (1 - pow(q / p, z - k));
- }
- return sum;
- }
- int main() {
- for (int i = 0; i < 10; i++) {
- printf("z=%d, p=%f\n", i, attackerSuccessProbability(0.51, i));
- }
- return 0;
- }
通過(guò)上述的計(jì)算我們會(huì)發(fā)現(xiàn),在無(wú)限長(zhǎng)的時(shí)間中,占有全網(wǎng)算力的節(jié)點(diǎn)能夠發(fā)起 51% 攻擊修改歷史的概率是 100%;但是在有限長(zhǎng)的時(shí)間中,因?yàn)楸忍貛胖械乃懔κ窍鄬?duì)動(dòng)態(tài)的,比特幣網(wǎng)絡(luò)的節(jié)點(diǎn)也在避免出現(xiàn)單節(jié)點(diǎn)占有 51% 以上算力的情況,所以想要篡改比特幣的歷史還是比較困難的,不過(guò)在一些小眾的、算力沒有保證的一些區(qū)塊鏈網(wǎng)絡(luò)中,51% 攻擊還是極其常見的[^9]。
防范 51% 攻擊方法也很簡(jiǎn)單,在多數(shù)的區(qū)塊鏈網(wǎng)絡(luò)中,剛剛加入?yún)^(qū)塊鏈網(wǎng)絡(luò)中的交易都是未確認(rèn)的,只要這些區(qū)塊后面追加了數(shù)量足夠的區(qū)塊,區(qū)塊中的交易才會(huì)被確認(rèn)。比特幣中的交易確認(rèn)數(shù)就是 6 個(gè),而比特幣平均 10 分鐘生成一個(gè)塊,所以一次交易的確認(rèn)時(shí)間大概為 60 分鐘,這也是為了保證安全性不得不做出的犧牲。不過(guò),這種增加確認(rèn)數(shù)的做法也不能保證 100% 的安全,我們也只能在不影響用戶體驗(yàn)的情況下,盡可能增加攻擊者的成本。
總結(jié)
研究比特幣這樣的區(qū)塊鏈技術(shù)還是非常有趣的,作為一個(gè)分布式的數(shù)據(jù)庫(kù),它也會(huì)遇到分布式系統(tǒng)經(jīng)常會(huì)遇到的問(wèn)題,例如節(jié)點(diǎn)不可靠等問(wèn)題;同時(shí)作為一個(gè)金融系統(tǒng)和賬本,它也會(huì)面對(duì)更加復(fù)雜的交易確認(rèn)和驗(yàn)證場(chǎng)景。比特幣網(wǎng)絡(luò)的設(shè)計(jì)非常有趣,它是技術(shù)和金融兩個(gè)交叉領(lǐng)域結(jié)合后的產(chǎn)物,非常值得我們花時(shí)間研究背后的原理。
比特幣并不能 100% 防止交易和數(shù)據(jù)的篡改,文中提到的兩種技術(shù)都只能從一定概率上保證安全,而降低攻擊者成功的可能性也是安全領(lǐng)域需要面對(duì)的永恒問(wèn)題。我們可以換一個(gè)更嚴(yán)謹(jǐn)?shù)姆绞疥U述今天的問(wèn)題 — 比特幣使用了哪些技術(shù)來(lái)增加攻擊者的成本、降低交易被篡改的概率:
- 比特幣使用了非對(duì)稱加密算法,保證攻擊者在有限時(shí)間內(nèi)無(wú)法偽造賬戶所有者的簽名;
- 比特幣使用了工作量證明的共識(shí)算法并引入了記賬的激勵(lì),保證網(wǎng)絡(luò)中的歷史交易不會(huì)被攻擊者快速替換;
通過(guò)上述的兩種方式,比特幣才能保證歷史的交易不會(huì)被篡改和所有賬戶中資金的安全。到最后,我們還是來(lái)看一些比較開放的相關(guān)問(wèn)題,有興趣的讀者可以仔細(xì)思考一下下面的問(wèn)題:
- 你對(duì)比特幣的未來(lái)是怎么看的?
- 如果要對(duì)比特幣發(fā)起一次 51% 攻擊篡改交易要花費(fèi)多少成本?