作者:Anony
本文介紹了一種在 Windows 電腦上給 ESP32 開發板燒錄固件、從而製作出 Jade-DIY 硬件簽名器的方法。
簡介:DIY 的 Jade
關於 Blockstream 公司推出的 Jade 硬件簽名器,Mi Zeng 提供了一份詳盡的評測。該評測介紹了 Jade 硬件簽名器的安全模型,以及一些具有特色的安全功能。
因為 Jade 的固件是完全開源的,我們只需基於與正式版 Jade 相同的硬件,就可以製作出功能相同的硬件簽名器(在下文中,我們將分別稱為 “正式版 Jade” 和 “Jade-DIY”)。
經過測試,我們發現,儘管某一些 Jade-DIY 在功能上無法做到與正式版 Jade 完全相同(下文就會講到其中一個原因:硬件基礎),但在安全特性上,Jade-DIY 跟正式版 Jade 是一樣的。正式版 Jade 所具備的安全特性(如:“虛擬安全芯片”、自我擦除 PIN 碼),Jade-DIY 都具有。這為 Jade-DIY 賦予了巨大的吸引力,因為可以使用相當便宜的硬件來製作簽名器。
而且,Jade-DIY 在基本功能上非常紮實,絕不遜色於現在市場上主流的簽名器。
硬件挑選
在 Jade 的 GitHub 庫中,有一個專門的頁面,介紹了可以製作成 Jade-DIY 簽名器的硬件。讀者需要關注的有兩個方面:(1)是否配備攝像頭,這也是該頁面分類的依據;(2)硬件本身的 USB VendorID 和 ProductID 與正式版的 Jade 是否一致。
後者決定了當我們使用 USB 連接製作好的 Jade-DIY 時,軟件錢包會不會將它識別成 Jade。如果不會,則使用起來會更麻煩。不過,這些硬件基本上都支持藍牙,因此總可以使用藍牙來連接簽名器(如果軟件簽名器支持的話,比如移動端的 Green Bitcoin Wallet)。此外,如果你選擇使用配有攝像頭的硬件,則總是可以使用 Air-gapped(隔空交互)的交互方式(主要就是掃碼),因此不必再介意這個問題。
本教程只針對沒有攝像頭的硬件。在這些硬件中,USB VendorID 和 ProductID 與零售正式版 Jade 一致的有(空格前是品牌名,空格後是型號):
- LILYGO T-Display
- M5Stack Basic Core
- M5Stack FIRE
出於經濟性的考慮,筆者選擇了 T-Display。在筆者購買之時,其本身的價格只需 65 元。讀者在採購時,應注意不要與 T-Display S3 相混淆。筆者購買的是編號為 Q125 的版本,為使用便利,可以單獨購買一個外殼(12 元)。據說自帶外殼的 K164 版本也可以製作成功。
下文就將以 T-Display 為示範。另外兩款硬件與 T-Display 使用相同的芯片,因此其刷機流程的相似的。
連接硬件
T-Display 的 USB 連接口是 Type-C 型的,讀者應另外準備好 Type-C 的 USB 連接線。連接 T-Display 之後,觀察其能否正常啟動。正常情況下,它會先顯示 “LILYGO” 的圖標,然後出現 “SD card mount failed” 的警示語。
然後,打開 Windows 的 “設備管理器”,查看 “端口(COM 和 LPT)” 項下是否有 “USB-Enhanced SERIAL CH9102 (COM3)” 一項。如無,則說明未正常連接,應該安裝驅動。下載並安裝驅動後,嘗試再次連接。
如果你安裝驅動後依然無法連接,請嘗試換一根 USB 連接線(有一些連接線只有供電功能,而沒有數據傳輸功能)。
上面提到的兩款 M5Stack 硬件與 T-Display 使用相同的 USBT 芯片,因此可以用相同的方式檢驗連接。
安裝開發工具
在ESP-IDF 的網站下載開發工具,請下載 “ESP-IDF v5.2.2 - Offline Installer”。打開安裝程序後,在選擇安裝內容的頁面,應該:(1)安裝 “Powershell 支持”;(2)在 “Chip Targets” 中,至少安裝 “ESP32” 和 “ESP32-S3”。(第一項 “Framework” 和第二項 “ESP-IDF 5.2” 一定不能省去)。
安裝好之後,嘗試在新的 PowerShell 窗口的菜單欄中,點擊 “+” 號,選擇 “ESP-IDF 5.2”,打開一個 ESP-IDF 環境。如果你的 PowerShell 窗口並不如圖所示,則請嘗試使用別的方式(比如 “開始” 菜單
下載 Jade 源代碼
首先,請確保自己安裝了 Git 軟件。這是一種版本控制工具,可用於下載開源軟件的源代碼。
在一個你喜歡的文件夾中,打開 PowerShell 窗口,輸入以下命令並運行:
git clone --recursive https://github.com/Blockstream/Jade.git
這行命令會新建一個 “Jade” 文件夾,並下載 Jade 源代碼。
接下來是本教程最重要的章節。
編譯燒錄固件
在燒錄固件時,可以選擇啟用或不啟用 “Secure Boot”。Secure Boot 的功能是給設備註入一個公鑰,並要求燒入的固件具備該公鑰的簽名。如果燒入的固件不具備有效的簽名,則設備會拒絕啟動。這是一種有用的安全措施,可以防止自己的設備被他人注入帶有惡意代碼的固件。Jade 源代碼庫中的 DIY 指南也推薦啟用 Secure Boot 功能。因此,本教程也強烈建議啟用 Secure Boot 功能。
下文的 “實驗性燒錄” 章節將介紹不啟用 Secure Boot 的燒錄流程;顧名思義,這主要是為了讓讀者熟悉刷機的流程。而 “安全燒錄” 將介紹啟用 Secure Boot 的燒錄流程。
注意,此處介紹的啟用 Secure Boot 的操作是不可逆的,一旦啟用,就無法取消。也即此後如果想要更新設備的固件,也必須使用相同的私鑰、簽名新的固件,才能刷入。弄丟這個簽名固件的私鑰將無法再給這個設備更新固件。
提前準備
CMD 中的 Python3
在開始燒錄之前,請先打開電腦的 “命令提示符(CMD)”,輸入 python3
並回車執行。如果它正確識別及執行,應該能在窗口中看到這樣的信息:
Python 3.12.3 (tags/v3.12.3:f6650f9, Apr 9 2024, 14:05:25) [MSC v.1938 64 bit (AMD64)] on win32Type "help", "copyright", "credits" or "license" for more information.>>>
如果程序的反應是打開 Windows 商店,說明 CMD 在得到命令 “python3” 時無法正確識別並執行 python 的對應版本,這會導致後續編譯中出現一個錯誤。必須修復這個錯誤。一種奇怪但有效的辦法是在你的 Python 文件夾中複製 “python.exe”,並粘貼到同一文件夾,然後將副本重命名為 “python3.exe”。
給出這個提醒是因為在筆者使用的兩臺 Windows 電腦(系統分別是 Win10 和 Win11)上,都出現了由此引發的編譯錯誤。
ESP-IDF 運行環境的運行文件夾
在任意文件夾中打開 “ESP-IDF 5.2” 運行環境;打開之後,它會自動運行一系列環境設置,以保證我們可以使用 ESP-IDF 的功能。運行成功後,它會輸出一系列信息,末尾是這樣的:
Go to the project directory and run: idf.py build
ESP-IDF 的初始運行環境是其安裝文件夾,比如說: ~\Espressif\frameworks\esp-idf-v5.2.2
,我們需要使用 cd
命令,切換到 “Jade” 文件夾。假設你的 “Jade” 文件夾的地址是 D:\esp\Jade
,那麼就在 ESP-IDF 運行環境中輸入:
cd D:\esp\Jade
最終,你的運行環境的開頭應該是這樣的:PS D:\esp\Jade>
。
OpenSSL
為了生成足夠安全的用於簽名固件的私鑰,請安裝 OpenSSL 軟件。
實驗性燒錄
在位於 “Jade” 文件夾的 ESP-IDF 運行環境中輸入以下命令:
cp configs/sdkconfig_display_ttgo_tdisplay.defaults sdkconfig.defaults
這行命令的作用是從 “configs”文件夾中複製一個配置文件,到 “Jade” 文件夾中。需要複製的配置文件當然是因設備而定的,這裡提供的是 T-Display 的配置文件。
如果你使用的硬件是 “M5Stack Basic Core”,則命令要改成:
cp configs/sdkconfig_display_m5blackgray.defaults sdkconfig.defaults
然後,運行以下命令:
idf.py buildidf.py flash monitor
第一行命令會將文件夾內的源代碼編譯成可以燒錄進入 T-Display 的固件,第二行則實際寫入,並在刷機成功後讓 T-Display 重啟。
以上就是實驗性刷入的過程。你可以把玩一下,看看 Jade-DIY 的功能。
如果你在刷機過程中出錯,導致 T-Display 無法正常開機、也無法連接電腦,那麼可以嘗試這個頁面介紹的操作:嘗試先斷開連接線,然後同時按住機身的三個按鈕,然後重新連接電腦。
安全燒錄
生成配置文件
在位於 “Jade” 文件夾的 ESP-IDF 運行環境中輸入以下命令:
./tools/mkdefaults.py ./configs/sdkconfig_display_ttgo_tdisplay.defaults NDEBUG SECURE
運行後,在 “Jade” 文件夾裡檢查是否有 sdkconfig
、sdkconfig.defaults
和 sdkconfig.defaults.orig
三個文件。
使用 “記事本” 打開 sdkconfig.defaults
文件,尋找其中是否有這幾行:
CONFIG_SECURE_BOOT=yCONFIG_ESP32_REV_MIN_3=y
如果沒有這幾行內容,或者沒有上述三個文件,請重複運行上述命令。
生成簽名固件的私鑰
然後,在 ESP-IDF 運行環境中運行以下命令、使用 OpenSSL 軟件生成用於簽名固件的私鑰:
openssl genrsa -out ../jade-diy-v2.pem 3072
該行會在 “Jade” 文件夾的上級文件夾中生成一個名為 jade-diy-v2.pem
的私鑰,該私鑰將用在固件的簽名中。
你可以使用別的文件名稱,也可以指定另一個文件夾。但這就需要你回過頭修改 sdkconfig.defaults
文件中 CONFIG_SECURE_BOOT_SIGNING_KEY=
一行中的相對地址。從便利和安全的角度出發,可以按上述命令生成私鑰;在完成燒錄後,將該私鑰移動到其它相對隱蔽的地方;當以後需要升級固件時,再將私鑰放回原位、簽名固件並燒錄。
生成引導加載程序和固件
在 ESP-IDF 運行環境中運行以下命令:
idf.py bootloaderidf.py build
第一行會生成引導加載程序。該程序負責執行 Secure Boot 的功能。第二行則生成執行實際功能的固件。
在運行第一行命令時,程序可能無法成功運行,因為 SDKCONFIG_DEFAULTS '~/Jade/sdkconfig.defaults.tmp' does not exist
。這時候,往往只需再次運行上文 “生成配置文件” 一節中的命令,就可以生成所需的 sdkconfig.defaults.tmp
文件。
寫入引導加載程序
在啟用 Secure Boot 之後,ESP-IDF 不會再自動刷入引導加載程序,因此,我們需要手動刷入。
在 ESP-IDF 運行環境中運行這條命令:
esptool.py write_flash --erase-all 0x1000 ./build/bootloader/bootloader.bin
在這裡,--erase-all
的意思是清空閃存中的全部內容(如果你在此前嘗試過實驗性燒錄,可能需要這個標籤);而後面的 0x1000
則代表寫入閃存的位置,後面則是待寫入的 引導程序的文件位置。
合理的寫入位置可能因設備而不同,如果你並不使用 T-Display,請仔細閱讀 idf.py bootloader
命令運行過程中出現在屏幕上的內容,它將提示你: Secure boot enabled...
(啟用了 Secure boot,因此引導程序不會自動燒錄);再下面就是一行能夠執行的命令,包含 python.exe
、esptool.py
字樣。可以複製該行命令來代替上面這行命令,也可以在該行命令中找出 0x
開頭的、表示閃存地址的字符,替換掉上文命令的 0x1000
然後執行。
如果你無法運行這行命令,則你可能是未正確安裝 esptool
,可以嘗試運行 pip install esptool
來解決。
寫入固件
在 ESP-IDF 運行環境中運行以下命令:
idf.py flashidf.py monitor
在運行第二行時,如果長時間運行不結束,可以同時按下鍵盤上的 “Ctrl” 和 “]” 鍵主動結束。看看 T-Display(現在應該叫 “Jade-DIY” 了)能否正常啟動。可嘗試按下設備頂部的重啟按鈕。
安全燒錄,完成!
更新固件
連接 Jade-DIY,在 “Jade” 文件夾下的 ESP-IDF 運行環境中,運行 python jade_ota.py --noagent
來更新固件。該過程可能需要安裝一些 python 的依賴,使用 pip install
來解決。
目前,T-Display 可用的最新固件版本是 1.0.31
,相對於正式版 Jade 的固件是落後的。
操作指南
- T-Display 機身一共有三個按鍵。在操作 Jade-DIY 時,機身頂部的按鈕是 “重啟” 鍵;單獨按下機身的兩個按鈕,可以移動屏幕上的光標;確認選擇時,則要同時按下這兩個按鈕。
- 在初始化 Jade-DIY(“Setup Jade”)時,Jade-DIY 會要求你設置一個 6 位數的數字 PIN 碼。該 PIN 碼在安全上極為關鍵。但是,要解鎖、使用 Jade-DIY 時,必須先使用一款適配的軟件錢包喚起 Jade-DIY,才能輸入 PIN 碼、解鎖。
- 這樣的軟件錢包有:桌面端:Sparrow Wallet、Electrum Wallet;移動端:Green Wallet。Jade-DIY 可用 USB 連接電腦,用藍牙連接手機。Jade-DIY 的藍牙功能默認關閉,需要手動開啟。
- 連接到軟件錢包後,使用體驗就跟主流的硬件簽名器沒有多大區別。當需要簽名交易時,交易的詳細信息將在屏幕上顯示。
- 解鎖 Jade-DIY 之後,可以在 “Duerase PIN” 中設置 “自我擦除 PIN 碼”。設置好之後,一旦在解鎖時輸入這個 PIN 碼,將刪除設備內的所有內容(包括加密的種子詞)。
- Jade-DIY 具備絕大多數 bitcoin-only 簽名器的功能,單籤、多籤都不在話下。
安全分析
Jade-DIY 的安全模型是什麼樣的?
在本教程中,筆者介紹了啟用 Secure Boot 的刷機流程;Secure Boot 是一項非常重要的安全措施,可以應對 Jade-DIY 被注入惡意固件的風險。這種風險是真實的,目前,幾乎所有的硬件簽名器都提供了這一方面的防護(比如 Keystone,在升級固件的時候也會校驗固件有無簽名)。
應用 Secure Boot 之後,經過測試,我們認為 Jade-DIY 的安全性跟正式版 Jade 是一樣的。那麼正式版 Jade 的安全性又如何?
如本文開頭提到的 Mi Zeng 的評測所說的,Jade 以 “虛擬安全芯片” 的設計,來處理 “安全芯片 vs. 開源” 的取捨:在加密保存種子詞的過程中,Jade 使用了來自一個遠程服務器的密鑰(與本地的 PIN 碼共同加密種子詞)。而在解鎖 Jade 的過程中,只有提供設置好的 PIN 碼,才能讓適配的軟件錢包跟遠程服務器通信、獲得這個密鑰。(這也是為什麼在使用其本身保存的種子詞時,必須跟適配的軟件錢包一起工作)。
因此,這種模式的安全性,是大於完全不使用安全芯片、也沒有額外設計的硬件簽名器的(比如較早版本的 Trezor 簽名器)。
不過,與使用了安全芯片並附加了自毀機制(拆機自毀、無效 PIN 碼輸入達一定次數後自毀)的簽名器相比,Jade 在應對設備被劫持之後的物理攻擊時稍顯不如。
總的來說,Jade-DIY 以較低的成本,提供了相當不錯的安全性,也提供了足夠強大的功能。
開源運動萬歲!
致謝
感謝 Mi Zeng 在本文撰寫階段給出的有益指引和探討,當然,文中一切錯誤由我自己負責。