
比特幣安全漏洞:時間扭曲攻擊
TechFlow Selected深潮精選

比特幣安全漏洞:時間扭曲攻擊
本文我們分析了比特幣的一個安全漏洞,即所謂的時間扭曲攻擊。
撰文:BitMEX Research

概述
2025 年 3 月 26 日,比特幣開發者 Antoine Poinsot 發佈了一個新的比特幣改進提案。這是一個被稱為「大共識清理」的軟分叉提案。該升級修復了多年來一直存在於比特幣協議中的幾個漏洞和弱點。其中一個漏洞是我們最近討論過的重複交易問題。另一個將被該清理軟分叉修復的更為嚴重的漏洞被稱為「時間扭曲攻擊」,這正是本文要討論的主題。
比特幣區塊時間戳保護規則
在討論時間扭曲攻擊之前,讓我們回顧一下當前的時間操縱保護規則:
中位過去時間 (MPT) 規則 — 時間戳必須比最後十一個區塊的中位時間更靠後。
未來區塊時間規則 — 基於 MAX_FUTURE_BLOCK_TIME 常量,時間戳不能比節點對等體的中位時間超前超過 2 小時。節點提供的時間與本地系統時鐘之間允許的最大差距是 90 分鐘,這是另一個安全保障。
MPT 規則旨在確保區塊不會太過於回到過去,而未來區塊規則則防止它們進入未來。請注意,不能實施類似於未來區塊規則的規則來防止區塊有過去的時間戳,因為這可能會影響初始區塊鏈同步。時間扭曲攻擊涉及偽造時間戳,使時間戳遠遠回到過去。
中本聰的「差一」錯誤
在比特幣中,一個難度調整週期包含 2016 個區塊,以 10 分鐘區塊目標計算,這大約是兩週的時間。為了計算挖礦難度調整,協議計算相關 2016 區塊窗口中第一個和最後一個區塊之間的時間戳差。這個 2016 區塊的窗口包含 2015 個區塊之間的間隔(即 2016 減一)。因此,使用的相關目標時間應該是 60 秒 * 10 分鐘 * 2015 個間隔,等於 1,209,000 秒。然而,比特幣協議使用數字 2016 來計算目標。60 秒 * 10 分鐘 * 2016 = 1,209,600 秒。這是一個差一錯誤。這是一個容易犯的錯誤,中本聰似乎混淆了區塊與區塊之間的間隔。
原始中本聰代碼

來源:https://sourceforge.net/p/bitcoin/code/1/tree//trunk/main.cpp#l687
這個錯誤意味著目標時間比應有的長 0.05%。因此,比特幣目標間隔時間實際上不是 10 分鐘,而是 10 分鐘零 0.3 秒。這個漏洞並不重要,實際上自比特幣啟動以來,平均間隔一直是 9 分鐘 36 秒,明顯少於 10 分鐘。這是因為自 2009 年以來,平均算力一直在增加。這就是為什麼最後的減半發生在 2024 年 4 月,而不是 2025 年 1 月。我們提前了進度。無論如何,中本聰這 0.3 秒的錯誤在整體上相當無關緊要。也許有一天,在遙遠的未來,當價格和算力停止增長時,這個漏洞會讓我們重新回到進度上。

雖然 0.3 秒的漏洞本身不是重大問題,但存在一個相關的問題,這是一個較為嚴重的漏洞。難度計算基於每個 2016 區塊窗口內的第一個和最後一個區塊。這也是錯誤的。在我們看來,相關週期應該是前一個 2016 區塊窗口的最後一個區塊與當前窗口的最後一個區塊之間的差異。這似乎是計算難度調整窗口長度的最合理方式,其中關鍵是時間跨度覆蓋不同的調整窗口。如果這樣做,那麼 2016 也將是計算目標的正確間隔數。也許中本聰犯這個錯誤的原因是他必須考慮第一個難度調整週期,而該週期從未有過前一週期的最後一個區塊可用。
時間扭曲攻擊
比特幣的時間扭曲攻擊約在 2011 年首次被發現,利用了中本聰在難度計算中犯的錯誤。要進行攻擊,假設挖礦是 100% 中心化的,礦工可以設置協議允許的任何時間戳。在攻擊中,對於幾乎所有區塊,礦工將時間戳設置為比前一個區塊前進一秒,因此區塊鏈在時間上向前移動,並遵守 MTP 規則。為了儘可能慢地向前移動時間,礦工可以連續六個區塊保持相同的時間戳,然後在下一個區塊中將時間增加一秒,以此類推。這意味著區塊時間戳每六個區塊向前移動一秒。
這種攻擊意味著區塊鏈會越來越落後於真實時間,難度會增加,使挖礦變得越來越困難。然而,為了增強攻擊效果,在每個難度調整週期的最後一個區塊中,礦工將時間戳設置為真實世界時間。下一個區塊,即每個難度調整窗口的第一個區塊,然後被設置回過去,比前一個難度調整窗口的倒數第二個區塊提前一秒。這仍然符合 MTP 規則,因為在這種情況下,一個異常不會影響 11 個區塊的中位數。
當進行這種攻擊時,第一個週期後的難度不會受到影響。然而,在攻擊開始後的第二個調整週期後,難度將向下調整。然後礦工可以以極快的速度創建區塊,可能創造大量比特幣,然後可能出售這些幣並獲利。
簡化說明
由於難度週期是 2016 個區塊,在圖表中說明這種攻擊可能很困難。因此,我們創建了以下場景來嘗試解釋這種攻擊。
-
每個難度調整窗口有五個區塊
-
目標間隔為 10 分鐘
-
MTP 規則基於最後三個區塊
-
每個區塊的時間戳增加一分鐘,除了每個週期的最後一個區塊,它使用真實時間戳
說明性時間扭曲攻擊

如上圖所示,有兩條曲線:
-
代表每個難度調整窗口最後一個區塊真實時間的曲線。隨著礦工越來越快地找到區塊,難度降低,這條曲線變得不那麼陡峭
-
代表其他區塊操縱時間戳的直線
比特幣時間扭曲攻擊計算
下表顯示了礦工如何以最極端的方式使用這種攻擊來操縱難度向下。

注意:協議允許的任何週期的最大難度調整是 4 倍,但在上表中沒有達到這個值
每個週期的難度向下調整漸近到略高於 2.8 倍。這是因為隨著每個週期在時間上變短,難度調整減速的速率降低。
在上表的第 11 個週期,在攻擊的第 39 天,每秒產生超過 6 個區塊,準確地說是每秒 10.9 個區塊。此時,分配給區塊的時間戳限制以不同的方式發揮作用。根據 MTP 規則,時間必須每 6 個區塊向前移動,最小的時間增量是 1 秒。因此,在這一點上,基於我們的理解,時間戳開始比真實時間前進得更快,區塊鏈時鐘開始向前移動,接近真實世界時間,但仍然遠遠落後。儘管如此,攻擊可以繼續,難度不斷降低,直到達到允許的最小值。
攻擊可行性
雖然理論上這種攻擊是毀滅性的,但實施它有一些挑戰。執行攻擊可能需要大部分算力。如果有誠實的礦工輸入誠實的時間戳,那麼攻擊變得更加困難。MTP 規則和誠實礦工的時間戳可能會限制惡意礦工時間戳可以回溯的程度。此外,如果誠實的礦工產生任何難度調整窗口的第一個區塊,該週期的攻擊將無法工作。另一個可能使攻擊更難執行的緩解因素是,它對所有人都是可見的。任何人都可以看到時間戳,在難度向下調整之前必須操縱四周的時間戳,可能給我們時間推出緊急軟分叉修復。
解決方案
修復這個漏洞相對簡單,儘管可能需要軟分叉協議更改。通過改變難度調整算法來計算不同 2016 窗口中區塊之間的時間跨度並完全修復差一錯誤,直接修復這個問題相當複雜。這可能也是一個硬分叉。另一種修復方法是取消 MTP 規則,而是要求時間在每個區塊中總是向前移動,雖然這可能意味著時間可能會卡在太遠的前方,也意味著礦工可能會因為在系統時鐘上使用真實時間而遇到麻煩,如果另一個礦工的時鐘提前幾秒,這可能會有無效的時間。
幸運的是,有一個更簡單的解決方案。為了防止時間扭曲攻擊,我們只需要要求新難度週期的第一個區塊的時間不早於前一週期最後一個區塊之前的特定分鐘數。這個新限制規則的分鐘數已經被討論過,提案從 10 分鐘到 2 小時不等。就緩解時間扭曲攻擊而言,兩者可能都可以。
在 Poinsot 的大共識清理提案中,他現在確定為 2 小時。2 小時僅約為難度調整週期目標時間的 0.6%,因此操縱難度向下的能力受到嚴格限制。我們在下表中總結了關於應使用的寬限期的討論:

歡迎加入深潮 TechFlow 官方社群
Telegram 訂閱群:https://t.me/TechFlowDaily
Twitter 官方帳號:https://x.com/TechFlowPost
Twitter 英文帳號:https://x.com/BlockFlow_News














