你無法審計的那一層
(The Layer You Cannot Audit)
我遵循了比特幣自主託管的所有規則,卻依然遭受了重大損失。到底哪裡出了問題?而我現在正在做出什麼改變。
7 月 30 日晚上,我的錢包顯示著一筆已經不屬於我的比特幣。
餘額看起來正常,地址看起來正常,我的硬體錢包也照常簽署了交易。
但網路拒絕了這筆交易。
那些幣早已被轉走了。
我參與比特幣領域已有多年,一直以來都在教授資產所有權、自主託管(Self-custody),以及「真正擁有資產」與「僅擁有他人承諾」之間的本質區別。我沒有將助記詞輸入過電腦,沒有將它備份在雲端,也沒有把它輸入到手機、網站或密碼管理器中。助記詞是在完全離線(氣隙Air-gapped)的簽署設備上生成的,經過了妥善備份與驗證。我的 Sparrow 錢包設定為唯讀模式(Watch-only),並連接到我自己的全節點。
我嚴格遵守了所有的規則。
但我依然失去了數額重大的比特幣。
最讓人難以接受的,並不是比特幣失敗了——比特幣並沒有失敗。最難接受的是,我遵守了每一條被公認的自主託管法則,但這依然不夠。
我不會公開損失的具體金額。因為數字會模糊焦點,而數字並不是這件事的核心教訓。真正重要的是:這並不是因為我點擊了釣魚連結、洩漏了復原助記詞,或是把資產控制權交給了任何人。
這場失敗,從助記詞產生的那一刻就已經注定了。
只是我當時渾然不知。
我是本週浮出水面的 COLDCARD 隨機數生成器(RNG)事件的受害者之一。目前的調查報告顯示,數百個單簽(Single-signature)地址在短短數分鐘內、跨越連續數個區塊被清空。Coinkite 事後已直接承認了這項缺陷:設備的隨機數生成功能存在漏洞,導致產生的助記詞熵值(Entropy)遠低於設計標準;任何理解該漏洞的人,都能藉此重構私鑰。Coinkite 目前表示 Mk3 是受影響最嚴重的型號,較新的設備雖亦受影響,但程度較輕。根據官方估計,Mk3 的有效搜尋空間被降至僅約 40 位元(bits),Mk4、Mk5 和 Q 則約為 72 位元,而原本應有的安全標準是 128 位元。
Coinkite 已發布了關於熵值失效的技術背景說明;完整的技術審查仍在進行中,因此部分細節仍屬初步結論。
然而,這件事所揭示的結構性教訓,並不取決於最終的數位鑑識結果。
私鑰的安全強度,完全取決於創建它時的隨機性。
而使用者在事後,是完全無法審計這種隨機性的。
這正是幾乎沒有人討論過的那一層。
不再真實的餘額
我並不是因為親眼看著比特幣被轉走才發現偷竊事件的。
我是因為嘗試進行一筆無關的交易,結果網路返回了錯誤訊息——提示該筆輸入(Inputs)已經被花費掉了,我才赫然發現。
當時我自己的全節點暫時無法連線,Sparrow 錢包無法查詢最新的區塊鏈狀態,因此它只顯示了上一次成功記錄到的餘額。雖然該餘額已是一天前的數據,但在螢幕上看起來依然像是當前狀態。
我的簽署設備隨後執行了它該做的事:完成交易簽署。
那道簽名證明了我擁有相應的私鑰,但它無法證明那些私鑰曾經控制的比特幣是否依舊未被花費。
只有區塊鏈網路才能確認這一點。
錢包裡的餘額並非資產本身,它只是對帳本當前狀態的一份報告。當報告背後的資料來源過期時,螢幕上的數字只是一幅已經不存在的過去景象。
這項差異在當前極為關鍵,因為受此事件影響的人,自然會打開錢包軟體,看到非零的餘額,便以為自己倖免於難。
千萬不要抱持這種假設。
請務必根據當前的區塊鏈狀態,親自檢查實際地址。盡可能使用您自己同步完成的節點;否則,請交叉使用多家聲譽良好的區塊瀏覽器,逐一驗證各個地址。根據回報,部分受害者似乎遭受了「部分清空(Partial sweep)」,這意味著剩餘的餘額並不能證明底層的助記詞是安全的。
- 餘額可能是過期的。
- 剩餘的部分餘額可能會造成誤導。
- 只有區塊鏈上的記錄才是唯一的真相。
究竟發生了什麼事
目前被報導的資產轉移模式呈現出異常高度集中。
迄今確認被掃空的輸出(Outputs)均為單簽地址(Single-signature)。在當前鑑識報告中描述的受影響地址中,並未出現多重簽名(Multisignature)。這些地址主要為原生 SegWit(Native SegWit),亦有極少數較舊的地址格式。有些錢包被完全清空,有些則似乎僅被部分轉走。
隨著調查深入,這些細節可能會有所調整。
但核心的事實極不可能改變:
如果攻擊者能夠重構控制單簽錢包的那唯一一把私鑰,該錢包就徹底淪陷了。
攻擊者不需要實體接觸設備,惡意軟體不需要穿透離線環境(Air gap),助記詞也不需要被拍照、複製或輸入到任何地方。如果私鑰是從不足的隨機性中生成的,那麼在第一筆存款進來之前,漏洞就已經存在了。
硬體錢包可以完好無損地放在保險箱深處。
而攻擊者可以在地球的另一端進行計算。
這正是這類失效如此危險的原因:它在使用者最缺乏透明度的地方擊敗了使用者——也就是「密鑰本身被創造的瞬間」。
你無法審計的那一層
比特幣給了我們極其強大的驗證工具:
- 你可以在簽署設備的螢幕上驗證接收地址。
- 你可以在簽署前驗證交易內容。
- 你可以驗證韌體簽名。
- 你可以驗證衍生路徑(Derivation path)。
- 你可以驗證備份。
- 你可以驗證多簽的法定人數。
- 你可以運行自己的全節點並驗證整個區塊鏈。
但是,絕大多數使用者無法獨立驗證:當他們的助記詞生成時,隨機數生成器是否提供了足夠的熵。
復原助記詞看起來可能完全隨機,設備可能會正常運作好幾年,錢包可以毫無問題地接收和發送交易。這一切都無法證明最初的隨機性在密碼學上是健全的。
如果熵值過弱,復原助記詞就無法獲得人們通常與比特幣私鑰聯繫在一起的那種龐大理論搜尋空間的保護。它所受到的保護,僅限於那個有缺陷的生成器所能產生的極小型輸出集合。
一旦攻擊者掌握了該生成器的模式,看似堅不可摧的安全性就會瞬間崩塌。
這並非弱隨機性第一次危害加密貨幣使用者。過去的 Milk Sad 漏洞揭露了 Libbitcoin Explorer 因極度不足的熵所生成的錢包,攻擊者在網路上瘋狂利用了這些私鑰。近期,研究人員又披露了 Ill Bloom 類型的錢包資金抽離事件,原因同樣出自弱隨機數生成器創建的復原助記詞。雖然軟體與情境不同,但結構性的失敗如出一轍:一個秘密看起來隨機,卻是由可預測的過程所產生的。
這種事將來還會再次發生。
不一定會發生在同一家製造商,不一定會發生在同一款設備。但總有一天,在某個地方,另一個實作版本會出錯。
唯一持久的應對之道,是構建一種託管架構:讓單一隱蔽的實作失敗,無法演變成毀滅性的徹底損失。
哪裡出了問題
有些人會利用這次事件聲稱「自主託管已經失敗了」。
它沒有失敗。
自主託管並非只有一種架構。
由一台設備生成、控制單一錢包的單一助記詞,是自主託管。
使用來自不同製造商的獨立設備建立「三取二(2-of-3)」多重簽名,也是自主託管。
這兩者所承擔的風險完全不可同日而語。
這次事件證明的不是「個人沒有能力持有比特幣」,而是證明了:將重大財富集中在單一秘密背後,會創造出一個最終的單點故障(Single point of failure)——即使持有者嚴格遵循了所有被認可的規則。
底層協定沒有失敗。比特幣沒有撤銷任何有效的交易。區塊鏈網路沒有搞錯所有權。
有效的私鑰完成了簽名,而網路完全按照設計執行了該簽名。
失敗的是圍繞著所有權所建立的架構。
單簽託管假設了:單一密鑰是健全的、單一軟硬體實作是健全的、且生成秘密的過程是健全的。只要其中任何一個假設失效,在缺陷與資產之間,就没有任何第二重批准防線。
一個設計合理的多重簽名(Multisig)架構能改變這一點:光是知道一把被破解的私鑰是不夠的;光是破解一台設備是不夠的;光是單一製造商出錯也是不夠的。
這不是對自主託管的否定。這才是真正嚴肅看待自主託管。
交易所託管並未因此獲得洗白
目前有另一種觀點正在抬頭,而它同樣危險:「這證明了人們應該把比特幣留在交易所。」
這根本無法證明這一點。
平心而論,如果有人把這筆資產放在一個始終保持財務健全且誠實的合格託管商那裡,他今天確實依然擁有這些幣。求真求實的態度要求我們明確承認這一點。
但這絕不意味著交易所託管是安全的。
這只不過是用一種風險類型去交換另一種風險類型罷了。
歷史並非虛構。Mt. Gox、FTX、Celsius、Voyager、BlockFi 等無數歷史教訓,各自展示了同一個真理的不同版本:由中間人持有的加密貨幣,始終暴露在中間人的償債能力、內部控制、利益動機、治理水平及法律處境之中。
倖存下來的託管商在事後看來總是理所當然地安全。而在倒閉之前,那些失敗者往往看起來也同樣聲譽卓著。
交易所託管並沒有消除信任,它只是把信任轉移到了一家機構身上——而存款人對該機構內部狀況的審計能力,甚至可能比對一個硬體錢包還要低。
當加密貨幣放在交易所時,持有者在失去存取權的那一刻之前,可能根本無法知道這些資產是被完全儲備、被抵押、被借出、被混用、被凍結,還是面臨著比自己優先級更高的債權要求。
所以,不:這次事件絕不能成為將改變人生的重大金額留在交易所的藉口。
它也不該被用來當作恐嚇人們遠離自主託管的工具。
正確且更加成熟的結論是:
我們的任務不是去尋找一個「風險完全消失」的神聖之地。
我們的任務是識別風險存在於何處,限制任何單一失敗所能造成的破壞程度,並建立一個能夠在單一元件失效後依然存活的結構。
只要設計得當,自主託管依然是長期持有重大比特幣資產的最佳歸宿。
但單簽集中託管並非自主託管的最高形式。它只是最簡單的形式。這兩者絕不能混為一談。
現在誰應該採取行動
根據目前回報的曝險情況,任何助記詞是在受影響的 COLDCARD 韌體關注點上記錄生成的人——尤其是上述的 Mk3 版本——都應該嚴肅看待此事件,特別是在該錢包為單簽且未使用強大、獨特的 BIP-39 密語(Passphrase)的情況下。
技術調查仍在積極進行中,因此受影響的使用者應依賴製造商最新的官方指引與可靠的安全研究,而非僅憑社交媒體上的摘要。
但任何有合理理由懷疑助記詞可能洩露的人,都不該在資金仍冒風險時等待完美的確定性。
在更新後的韌體(Mk3 4.2.0 或更高、Mk4/Mk5 5.6.0 或更高、Q 1.5.0Q 或更高)或您信任的其他設備上,生成一個全新的助記詞。
根據 Coinkite 的說明,更新至 4.2.0 後,空的 Mk3 可以透過手動輸入至少 99 次公正、獨立、私密的擲骰子結果來構建替代助記詞,從而完全繞過設備內部的隨機數生成器。
不要將舊的助記詞還原到新設備上並稱之為遷移。還原舊助記詞只會完整複製舊有的漏洞。
直接在目標簽署設備上驗證新的接收地址。轉移全部的曝險餘額,切勿在您認為可能受損的金鑰上故意留下零頭(Change)。
然後,識別並重新定向每一個可能繼續向舊錢包發送比特幣的系統:
- 交易所提款地址
- 定額定投(Recurring purchases)
- 礦池收益發送
- 客戶發票
- 儲存的地址簿
- 自動轉帳與固定指令
否則,受損地址在原始餘額轉走後仍會繼續接收資金,讓一場已經結束的災難變成持續性的「捐款」。
使用 BIP-39 密語(Passphrase)的使用者可能會獲得額外的保護,具體取決於該密語是如何創建與使用的。然而在精確的攻擊機制調查清楚之前,不要把潛在保護誤認為絕對的安全。Coinkite 聲稱,使用至少 50 次公正、獨立、私密的擲骰子生成的助記詞,單就此漏洞而言不被視為處於風險中。
當潛在損失金額重大時,請直接進行遷移。
如果不幸檢查時資金已被轉走,在做任何事之前請先記錄一切:受影響的地址、清空資金的交易 ID(TxID)以及時間戳記。這些記錄是未來進行分析、報案及任何可能追討的依據。隨後,將剩餘資金從該助記詞派生的每一個地址中移走(包括目前仍顯示有資金的地址)。
此類事件往往會吸引冒充者。任何製造商、錢包提供商或交易所絕不會向您索取助記詞,不會主動透過私訊聯繫您,也不會要您將資金發送到他們提供的地址。遷移過程僅發生在您已經控制的軟體內部、進入您自己掌握密鑰的錢包中。任何主動聯繫並聲稱協助您轉移加密貨幣的人,都是想騙走您的資產。
如果您的比特幣存放在包含受影響金鑰的多簽錢包中,在準備遷移期間有一個更快的臨時保護步驟(Nunchuk 本週公布了該機制):從某個地址花費資金會永久在鏈上揭露其公鑰,攻擊者重構受影響的助記詞後,僅凭公開資料就能比對並定位該地址。如果您從未花費過資金的地址則不具備這種直接曝險。將資金從先前使用過的地址中移出,能在幾分鐘內堵住最容易被利用的漏洞。
如果您是在幾個月或幾年後看到這篇文章,請不要以為危險是一模一樣的。具體的技術漏洞可以被修復,但結構性的教訓永不過期。
我正在做出什麼改變
多年來我一直推薦 COLDCARD。
在 2021 年的短暫期間,我也曾是 COLDCARD 的推廣合作者(Affiliate)——這是我與 Coinkite 唯一的商業關係。在該關係之前、期間以及結束很久之後,我都一直在推薦這款產品,因為我當時認為它是市面上最強大的純比特幣(Bitcoin-only)簽署設備之一。
比特幣社群中許多非常嚴肅且受人尊敬的人士也達成了相同的結論。
當時的推薦並非失去理性,而是基於當時所能獲取的最佳資訊。
但這次的經歷徹底改變了我對「負責任託管」的認知。
不是因為每台 COLDCARD 都不安全,不是因為現在應該懷疑所有的硬體錢包,更不是因為自主託管是一個錯誤。
它改變我的觀點是因為:任何單一製造商、任何單一實作、任何單一設備,都可能以使用者無法察覺的方式默默出錯。
沒有任何聲譽可以消除這種可能性。沒有任何品牌應該作為唯一的授權點,托起無限數量的比特幣。
我正在採納三條原則:
原則一:重大資產採用「多廠商多重簽名」(Multi-vendor Multisig)
如果法定人數中包含相關聯的風險,光是多重簽名也是不夠的。
如果「三取二」架構中的兩把私鑰是由同一個型號、同一個韌體家族或同一家製造商生成的,它依然集中了實作風險。製造商範圍內的缺陷可能會影響法定人數中的一把以上的私鑰。
重大資產應使用來自不同製造商的獨立簽署設備。
這樣做目的不是追求視覺上的多樣性,而是追求失敗的獨立性(Failure independence)。
如果一家廠商被破解、出錯、被脅迫、存在缺陷或純粹弄錯了,這場意外最多讓多簽法定人數失去一把金鑰——而不是失去整個錢包。
沒有單一設備能夠獨自動用資金,沒有單一設備能夠獨自弄丟資金。
原則二:為每個託管層級設定書面上限
一個只由「用途」定義而沒有「最高金額」限制的錢包,終究會發生「風險漂移(Risk drift)」。這件事就發生在我身上。
一個錢包一開始可能只是用來存放日常資金的便利場所。隨著時間推移,存款陸續進入,每一次單獨的轉帳看起來都很合理,沒有哪一筆大到足以觸發整個架構的重構。最終,錢包裡積累的金額,徹底脫離了保護它的底層架構所能承載的能力。
沒有最高配額限制的錢包,不叫階梯式託管,那是對風險漂移的公開邀請。
每個錢包都應該有明確的書面上限。當餘額超過該上限時,超出部分應自動轉移到更強大的結構中。不是等到方便的時候,不是等下一筆存款進來後,也不是等市場上漲之後。而是自動執行。
託管架構需要風險控制上限,這與投資組合需要風控的理由完全相同。危險極少發生在某個戲劇性的單一決定中,它往往累積於一連串單獨看起來都無害的決定之中。
原則三:單簽僅適用於「承受得起損失」的金額
這不是一條針對 COLDCARD 的規則,這不是一條針對任何特定製造商的規則。這是一條關於「結構」的規則。
單簽意味著:單一秘密可以授權一切。因此,單一未被發現的缺陷可以奪走一切。
對於日常消費餘額、戰術性持有、旅遊錢包,以及損失後不會實質改變你生活的金額,這種折衷是可以接受的。但對於足以改變人生的重大金額,這絕對不可接受。
單簽不是用來存放「你預期會失去」的金額,而是用來存放「即使失去也不會毀掉你」的金額。
僅僅「擁有」是不夠的
多年來我一直寫道:比特幣是無需用於即時開支的資本的終極歸宿。我至今依然深信不疑。
這次事件完全沒有改變比特幣的貨幣特性:沒有改變其固定總量,沒有改變其無發行者的本質,沒有改變結算的終局性(Finality),也沒有改變無須許可即可擁有資產的能力。
但是在「擁有比特幣」與「正確持有比特幣」之間,存在著巨大的鴻溝。
本週,我以極其高昂的代價學到了這個教訓。
協定沒有失敗。比它更深的一層在暗中失敗了——甚至可能在偷竊顯現的數年之前就已經失敗。
我手握助記詞,我擁有設備,我有妥善備份,我嚴格遵守了規則。
但我唯一沒有的,是一個能在「一切所依賴的那唯一金鑰失效後」依然存活下來的架構。
自主託管並不意味著「什麼都不信任」。它的真正涵義是:明確決定信任保留在何處,並確保沒有任何單一被信任的元件能夠帶走一切。
這就是給我們的教訓:
- 不是放棄自主託管。
- 不是把你的未來交給交易所。
- 不是去尋找一個「永遠不會出錯」的神級製造商。
- 建立一個「即使單一製造商出錯,你依然能存活下來」的架構。
- 建立一個「即使單一金鑰暴露,也不足以動搖資產」的架構。
- 建立一個「沒有任何單一缺陷能成為最終絕響」的架構。
除此之外的一切,都不過是在賭「某一底層永遠不會失效」。
而這場賭局,我再也不會參與了。