跳至主要内容

安全審查

發布之前,BitTool Signer 1.0.0 的原始碼在每個平台上都接受了兩次 AI 輔助的安全審查,各次審查分別獨立進行。四份報告均在下方全文公開。沒有一次發現嚴重或高風險問題。iPhone 版的兩次審查各發現一項低風險問題;Android 版的審查發現了中風險問題,其中有四項中風險等級的發現事項在已發布的 Android 1.0.0 中尚未解決,而且其中三項位於兩款 App 共用的簽名引擎中。

請先了解這些限制
  • 這些都不是資安公司進行的稽核,也都沒有人類稽核員參與。
  • Opus 5 與 Opus 5.5 審查出自同一模型家族,受審程式碼中相當一部分也由它撰寫或修改。報告指出,不得將其作為第三方證明或認證。
  • GPT-6 Astra 的審查說明,它們是為專案擁有者撰寫的 AI 輔助工程審查,而非稽核機構出具的認證,也不是人工簽核。
  • 兩份 Android 報告都建議,在用這款 App 保護大額資產之前,先修正尚未解決的中風險發現事項。 BitTool Signer Android 1.0.0 發布時這些問題仍未解決;請參閱所有發現事項。
  • 獨立的第三方稽核尚未進行。 報告將它與實機測試、使用真實第三方錢包的往返測試一起,列為存放大額資金之前仍需完成的工作。

BitTool Signer iPhone 版​

兩份報告​

Opus 5GPT-6 Astra
日期2026 年 10 月 19 日2026 年 10 月 18 日(報告 BTS-SEC-2026-1018-R3)
審查的程式碼標籤 v1.0.0,commit f62137210 月 18 日的工作目錄:commit 3d706b7,加上 59 個已變更的檔案與一個新測試
審查的引擎(signer.js,SHA-256)6933d0d8…f210776933d0d8…f21077
方法逐行審查原始碼(3,546 行 JavaScript、11,858 行 Swift)、11 項攻擊探測、以 4,000 個案例對 QR 輸入進行變異測試、測試套件、在乾淨環境中重新建置依子系統審查原始碼、與上一輪比較、獨立製作的 Bitcoin 與 Solana 測試資料、1,509 個案例的變異測試、測試套件、可重現建置、相依套件安全公告
執行的測試210 項引擎測試、168 項原生測試210 項引擎測試、177 項原生與 UI 測試
結果嚴重 0 · 高 0 · 中 0 · 低 1 · 資訊 3嚴重 0 · 高 0 · 中 0 · 低 1 · 觀察 4
獨立性自行審查,審查者也是大量程式碼的作者AI 輔助,為專案擁有者準備

兩次審查檢查的是 BitTool Signer 1.0.0 所發布的同一個引擎檔案:所有交易解析器、風險規則與簽名計畫都在其中。App 的其餘部分(介面、鑰匙圈、儲存)則是透過閱讀 Swift 原始碼來審查。

所有發現事項​

ID嚴重度發現事項在 1.0.0 中的狀態
BTS-OP5-01低高風險同意只由介面強制執行。 引擎要求部分解碼與不透明的請求必須經過明確確認,但對完全解碼的高風險請求(無上限授權、setApprovalForAll、Safe 權限變更、代幣銷毀)則沒有這項要求。App 會在勾選核取方塊之前停用簽名按鈕,因此攻擊者在 1.0.0 中無法觸及這個問題;它仍然重要,是因為引擎是使用者可以透過雜湊值驗證的部分。未解決。報告建議在 1.0.1 中將這項檢查加入引擎。
R3-01低含找零的銷毀交易之 Bitcoin 摘要。 對於含有金額不為零的 OP_RETURN 輸出且有經驗證找零的交易,結果畫面與活動紀錄中的簡短摘要會顯示「Every output returns to your wallet」(所有輸出都回到你的錢包)。簽名畫面本身則會正確顯示銷毀、其金額與高風險。未解決(1.0.0 所發布的引擎就是受審查的版本)。
BTS-OP5-02資訊活動紀錄中有一個在地化鍵(localization key)是由引擎輸出組成的,而 SwiftUI 會將它以 Markdown 呈現。目前它可能出現的每個值都是固定標籤,因此這只是潛在問題。未解決,潛在問題。
BTS-OP5-03資訊保險庫的密碼 KDF(PBKDF2-HMAC-SHA256,600,000 次迭代)不具記憶體困難特性。這由第二層加密加以緩解:該層使用綁定裝置的鑰匙圈金鑰,因此單憑一份複製出去的保險庫檔案,根本無法發動攻擊。已接受;建議在未來的保險庫格式中採用 Argon2id。
BTS-OP5-04資訊Solana 衍生過程中的 Ed25519 中間金鑰材料不會被明確抹除;真正起作用的控制措施是捨棄 JavaScript 環境。未解決,固有限制。
O-01資訊匯入期間,一項較慢的「這個錢包是否已存在?」查詢可能在助記詞被編輯之後才完成,並為前一個錢包提供密碼重設。重設本身會重新衍生錢包身分並拒絕錯誤的錢包;任何保險庫都不會改變。報告撰寫時尚未解決。
O-02資訊Safe 與 Solana 的摘要來自範圍受限的解碼器,而不是實際執行交易的結果。離線時無法得知即時的合約狀態。設計如此;已在審核畫面中說明。
O-03資訊在 Swift 與 JavaScript 中無法保證完全清零記憶體;實體裝置、作業系統的亂數產生器與所發布的二進位檔都未經測試。限制。
O-04資訊六項僅限開發環境的相依套件安全公告(3 項中度、3 項低度)。受影響的套件不在所發布的引擎中。維護事項。

兩份報告也重新測試了前兩輪審查的發現事項,包括一項高等級問題(含有 DELEGATECALL 與巢狀 MultiSend 的 Safe 多重簽名交易摘要),以及 Bitcoin 手續費與 Solana 銷毀摘要中的數項低等級問題,並確認它們都已修正。Opus 5 另外指出,TRON 簽名不帶有網路識別碼;這是 TRON 協定的特性而非缺陷,App 也會說明這一點。

之後在共用引擎中發現的問題​

BitTool Signer iPhone 1.0.0 隨附的引擎 SHA-256 為 6933d0d8…f21077。GPT-6 Astra 對 Android 版的審查正是針對這個檔案重現了引擎方面的發現事項,而 Opus 5.5 發現事項所涉及的 Bitcoin、EVM 與 TRON 程式碼在該檔案中也完全相同。因此,這些引擎方面的發現事項同樣適用於 iPhone 1.0.0:

ID嚴重度對 iPhone 1.0.0 的影響
BTS-02、BTS-07中與一筆極小轉帳一起送出的 Solana 銷毀、權限變更或授權委託,會被摘要顯示為那筆轉帳。詳情中的警告與風險確認仍然保留。
BTS-08中錢包單簽設定下任意位址索引的比特幣找零都會被接受,包括觀察錢包永遠不會掃描到的索引。
BTS-09低至中對於未知的 EVM 或 TRON 合約呼叫,保存的摘要不包含隨呼叫送出的原生幣。審核卡片會顯示它。

上文的 R3-01 與 Android 的 BTS-04 是同一缺陷,Android 版引擎已將其修正。Opus 5.5 報告建議在共用引擎中修正其餘問題,修正隨後會同時進入兩款 App。

審查確認了什麼​

領域確認內容詳情
簽名在 Release 建置中,唯一的簽名方式是透過固定的計畫。六項彼此獨立的檢查將簽名綁定到審核過的請求、計畫中的錢包與獲准的金鑰,而且引擎在簽名前會從解密後的種子重新衍生一切。已透過實際執行確認。簽名前的檢查
隨機性助記詞來自 SecRandomCopyBytes;發生錯誤時會中止建立,且沒有任何備援。引擎的 crypto.getRandomValues 與 Math.random 都橋接到同一個來源。種子產生
金鑰儲存兩層帶有經驗證標頭的 AES-GCM、僅存在於本裝置的鑰匙圈金鑰,以及重新啟動後依然有效的失敗嘗試延遲機制。金鑰儲存
拒絕本文件所描述的每一項拒絕都成立:SIGHASH_NONE/SINGLE/ANYONECANPAY、缺少前一筆交易的 SegWit v0 輸入、Solana 查找表、EIP-7702、blob 交易、對原始雜湊簽名的 eth_sign,以及不支援的 chain ID。限制與錯誤
不受信任的輸入兩次審查共使用 5,509 個經變異的 QR、CBOR、PSBT 與 JSON 輸入:無效輸入一律未被接受,也沒有任何未受控的例外。UR 與 CBOR
離線既未連結 CFNetwork,也未連結 Network.framework,且 JavaScript 橋接層不提供任何網路 API。安全模型
供應鏈引擎可從標籤逐位元組重建;執行階段相依套件都鎖定確切版本;針對正式環境相依套件的安全檢查(dependency audit)未回報任何漏洞。見下文

審查未涵蓋的範圍​

實體裝置上的測試(故障注入、記憶體傾印、旁路通道)、作業系統的亂數產生器與 Secure Enclave 的內部運作、App Store 二進位檔中引擎檔案以外部分的來源證明、在實際運作的鏈上進行交易、與第三方錢包的往返測試、密碼學相依套件的完整稽核、21 種介面語言的語言審閱,以及形式化驗證。通過的測試套件只涵蓋它所測試的案例,而非所有交易或裝置。

自行驗證引擎​

App Store 上的執行檔無法逐位元組重現(Apple 會重新簽署並加密它),但引擎是未加密的資源檔,可以直接比對。從標籤建置引擎:

git clone https://github.com/bitbill/bittool-signer-ios
cd bittool-signer-ios && git checkout v1.0.0
cd engine && npm ci --ignore-scripts && npm run build
shasum -a 256 ../BitToolSigner/Resources/signer.js
# 6933d0d8a6f60faa8222506ac0bd7eef80eb884c9f73e31e9f354b4740f21077 (1,181,026 bytes)

接著將它與你所安裝 App 內的檔案比對:以 Apple Configurator 將 App 下載為 .ipa,解壓縮後計算 Payload/BitToolSigner.app/signer.js 的雜湊值。完整步驟(包括驗證能做到哪裡為止)請參閱儲存庫中的 Reproducible-Build.md。

BitTool Signer Android 版​

兩份報告​

Opus 5.5GPT-6 Astra
日期2026 年 10 月 25 日2026 年 10 月 24 日
審查的程式碼正式版 1.0.0(版本代碼 1000001):程式碼提交 71af693,發布紀錄 62996b8發布之前的提交 e7e71fb:針對上一基準 bb1e656 之後變更的複審
審查的引擎(signer.js,SHA-256)4b371759…00fa196933d0d8…f21077,即 iPhone 1.0.0 隨附的引擎
方法分五個領域進行原始碼審查,每個領域都端到端追蹤;每項發現事項都對照程式碼複核;以合成資料重現引擎問題;檢查相依套件與建置產物審查變更的程式碼及其呼叫端,驗證三項修正,針對已提交的引擎套件重現問題,執行自動化回歸檢查
執行的測試2,075 項 App 測試、217 項引擎測試,發布驗證腳本 25 項全部通過1,616 項 Android 測試;210 項引擎測試,其中一項失敗、一項未實際執行就顯示通過(BTS-06)
結果嚴重 0 · 高 0 · 中 4(其中一項評為低至中)· 低 9 · 若干資訊性說明嚴重 0 · 高 0 · 未解決:中 1、低 1、驗證類 1 · 已解決 3
建議在面向保護大額錢包的正式發布之前,修正 BTS-07、BTS-08 與 BTS-10在該版本下,暫緩面向大額錢包的正式發布
獨立性受審程式碼中很大一部分出自同一模型家族AI 輔助;未修改正式環境程式碼

兩次審查都涵蓋了整個 Android App:Kotlin 模組、原生宿主(基於 QuickJS 的 JNI 層及原生 PBKDF2),以及與 iPhone 版共用的簽名引擎。

所有發現事項​

Opus 5.5 審查的就是正式發布的程式碼,因此以下是 BitTool Signer Android 1.0.0 的發現事項。

ID嚴重度發現事項所在位置
BTS-07中Solana 權限變更可以藏在一筆極小轉帳之後。 一個請求若在變更帳戶擁有者或權限、授權委託人或包含不透明指令的同時,附帶一筆 1 lamport 的轉帳,標題與保存的摘要都只會顯示這筆轉帳。詳情中的高風險警告仍然保留,也仍需進行風險確認。共用引擎,iPhone 版同樣存在
BTS-08中比特幣找零在任意索引上都會被接受。 只要某個輸出的腳本與錢包任一單簽設定相符,無論在分支 0 或 1、索引最高到 2³¹−1,都會被視為已驗證的找零。送往這類位址的資金在審核時顯示為「所有輸出都回到你的錢包」,但只掃描有限位址範圍的錢包可能永遠找不到它們。共用引擎,iPhone 版同樣存在
BTS-09低至中對於合約呼叫,保存的摘要不包含原生幣金額。 一個同時送出原生幣的未知 EVM 或 TRON 合約呼叫,會被保存為「未知合約呼叫」。審核卡片及其警告會顯示這筆金額。共用引擎,iPhone 版同樣存在
BTS-10中發布簽署金鑰存放在開發機上。 金鑰及其密碼以明文保存在工作目錄中(已排除在 Git 之外)。發布流程
BTS-11低在 App 鎖畫面後方,QR 碼相機可能仍持續掃描。簽名仍然需要錢包密碼。Android App
BTS-12低對於完全解碼的高風險請求,風險確認只由介面強制執行。Android App(iPhone 版:BTS-OP5-01)
BTS-13低在 Android 8–11 上發生 Keystore 錯誤後,用來驗證公開錢包資料的金鑰可能被重新產生,錢包隨後需要「修復」。不會遺失任何機密或資金。Android App
BTS-14低兩把輔助金鑰沒有檢查螢幕鎖定,部分文件也誇大了保護程度。保險庫本身仍然要求設定螢幕鎖定。Android App
BTS-15低預設的工作親和性(task affinity)使舊版 Android 上可能出現工作劫持。Android App
BTS-16低備份檢查可以透過反覆嘗試而通過。Android App(依報告,iPhone 版相同)
BTS-17低12 個字助記詞的一張復原卡只剩約 40 位元熵。Android App
BTS-18低取消錢包比對後,審核畫面可能停在「正在尋找相符的錢包…」。Android App
BTS-19低Android 8.0–9 無法偵測只覆蓋確認控制項一部分的覆蓋層。簽名仍然需要密碼。Android App

報告還列出了一些資訊性說明,例如:引擎執行緒沒有 CPU 時間上限(只影響可用性);在設定獨立的上傳金鑰之前,Google Play 版使用 APK 金鑰簽署;重試延遲以系統時鐘為準;以及 JVM 無法抹除的短暫助記詞副本。

GPT-6 Astra 審查的是較早的提交。它的發現事項以及在正式版中的狀態:

ID嚴重度發現事項在 e7e71fb 中在 Android 1.0.0 中
BTS-01中部分被遮住的「簽名」與風險確認控制項可能透過覆蓋層被點按已解決已解決
BTS-02中與極小轉帳混合的 Solana 銷毀或權限變更被摘要顯示為那筆轉帳未解決銷毀問題已修正;權限變更問題仍存在,即 BTS-07
BTS-03低操作取消後,機密緩衝區可能殘留已解決已解決
BTS-04低含找零的比特幣銷毀被摘要為「所有輸出都回到你的錢包」(即 iPhone 的 R3-01)未解決已修正
BTS-05功能中斷的 QR 碼掃描無法恢復已解決已解決
BTS-06驗證過時的檔案路徑導致一項引擎測試失敗、另一項未實際執行就通過未解決已修正(217 項引擎測試全部通過)

審查確認了什麼​

領域確認內容
簽名沒有繞過密碼的方法,除了已審核且已比對的請求之外無法簽署任何內容。簽名計畫與請求雜湊值、計畫雜湊值和待簽位元組摘要綁定;引擎會對照解密後的種子重新解析計畫,並拒絕對未簽名比特幣交易的任何更動。取消、App 鎖或新請求之後遲到的結果會被捨棄。
金鑰儲存原生程式碼中的 PBKDF2-HMAC-SHA256(600,000 次迭代)、每次加密都使用新隨機數與鹽值的 AES-256-GCM,再加上每個錢包一把不可匯出的 Android Keystore 金鑰(手機支援時使用 StrongBox)。每次密碼嘗試都在金鑰衍生之前計數,計數器損壞時一律拒絕。
記憶體中的機密解鎖後的機密保存在用完即關閉的容器中,即使操作被取消也會被抹除。助記詞透過 App 自帶的鍵盤輸入,任何輸入法都看不到。
引擎宿主引擎套件依 SHA-256 與長度固定;QuickJS 在沒有 eval 與 Function 的情況下執行,每個涉及機密或不可信輸入的操作都使用全新的執行環境,並設有記憶體與堆疊上限。
離線與平台沒有網路權限,也沒有連網程式碼。只匯出主畫面,沒有深層連結;備份與裝置轉移被排除在外;所有視窗都不會出現在截圖、錄影與最近使用的應用程式中;在 Android 12 以上版本會隱藏其他 App 的覆蓋層。App 鎖永遠不能授權簽名,發布版不輸出任何日誌。
供應鏈在乾淨的 npm ci --ignore-scripts 之後重新建置的引擎,與已提交的檔案以及 APK 中的副本逐位元組一致。正式環境相依套件稽核沒有回報任何安全公告。

審查未涵蓋的範圍​

未涵蓋的範圍包括:實機測試(不同製造商的 Keystore 與 StrongBox 行為、生物辨識、覆蓋層、螢幕擷取)、惡意覆蓋層攻擊演練、旁通道、原生程式碼在 ARM 上的執行、真實區塊鏈上的交易、Maven 與原生相依套件的 CVE 掃描,以及 Google Play 建置的副本。兩份報告都要求在 Android 8 到最新版本的代表性裝置上檢驗發布版,Opus 5.5 也建議在這款 App 保護大額資金之前進行獨立的人工稽核。

驗證 APK 與引擎​

在 bittool.com/signer 發布的 APK 可以完整核驗:檔案雜湊值、簽署憑證、其中的引擎,以及沒有網路權限(aapt2 dump badging 列出的權限中沒有 android.permission.INTERNET)。

# 1. The APK from bittool.com/signer
shasum -a 256 BitToolSigner-1.0.0-1000001.apk
# 109dbf5c622ee77672904c34a10229df3c9b0eac45b07096c510b1e1e169c2a4
apksigner verify --print-certs BitToolSigner-1.0.0-1000001.apk
# Signer #1 certificate DN: CN=BITTOOL PTE. LTD., O=BITTOOL PTE. LTD., C=SG
# Signer #1 certificate SHA-256 digest: af41ed101765393ae89038eb4c6fc7fa96d930f6fcd76b881437a39b5a9e4631

# 2. The engine inside it
unzip -p BitToolSigner-1.0.0-1000001.apk assets/engine/signer.js | shasum -a 256
# 4b3717599e8ee3ed9d2480e640e7203731543cc8ab0f2c3cec3b78e6f400fa19 (1,181,432 bytes)

# 3. The same engine, rebuilt from source
git clone https://github.com/bitbill/bittool-signer-android
cd bittool-signer-android && git checkout 71af693
cd engine && npm ci --ignore-scripts && npm run build
shasum -a 256 ../core/engine/src/main/assets/engine/signer.js

憑證在各個版本之間永不改變,Android 只會安裝帶有相同憑證的更新,App 也會在「設定 › 完全開源 › 本次建置」中顯示它。從 Google Play 安裝的副本是另一個檔案,因為 Google Play 會依上傳的套件重新建置,所以無法比對它的雜湊值;但其中的 assets/engine/signer.js 不會改變,可以在 adb pull 之後以同樣方式比對。完整步驟見程式碼儲存庫中的 Reproducible-Build.md。我們已於 2026 年 10 月 25 日對照發布的 APK 核對了上述數值。

下載報告​

報告頁數SHA-256
iPhone · Opus 5,2026 年 10 月 19 日(PDF,118 KB)17ff7ddd17e5dffccd99db6aaa43b8f0041167b58bd9b2bd7cc11d185e779bca1a
iPhone · GPT-6 Astra,報告 R3,2026 年 10 月 18 日(PDF,46 KB)1602d7a358f8f35b2978eab7db1292add4365a94b736ff79e158dee3afb842b64a
Android · Opus 5.5,2026 年 10 月 25 日(PDF,252 KB)88242d58aeec1aa88823eb0a938c9461b0681abfab3f37805e2f77a41b3bba34c
Android · GPT-6 Astra,複審,2026 年 10 月 24 日(PDF,22 KB)7b37aaefd40d0d522384a86255accadeb976067175d76e38466a1b4c90b036f53

本頁的摘要由我們撰寫;若措辭與報告有出入,以報告為準。