簽名器在簽名前會檢查什麼
來自連網裝置的 QR Code 是不受信任的輸入。BitTool Signer 將每個請求都視為可能具有敵意,並對每條鏈執行相同的處理流程:
- 1組合 QR 幀,並嚴格解碼請求(CBOR、PSBT、交易位元組)。
- 2解析將被簽署的確切位元組並建立審核內容:金額、收款人、手續費、合約呼叫、警告。
- 3僅使用公鑰將請求與本機錢包比對,並確立一份與請求雜湊綁定的簽名計畫。
- 使用者審核、確認風險、輸入密碼 ▶
- 4從種子重新衍生金鑰,並在使用前與計畫核對。
- 5簽名、驗證新簽名,並以請求本身的格式編碼回應。
嚴格解碼
在執行任何鏈的邏輯之前,會先驗證傳輸層:
- CBOR 必須使用確定長度,不得有重複的 map 鍵,不得有多餘的尾端位元組,巢狀層級最多 24 層、項目最多 20,000 個。未知的請求欄位會被拒絕。
- 動態 QR Code 必須來自同一個工作階段。混合兩個請求的幀會被視為錯誤,而不會合併。
- 大小限制:2,048 幀、每幀 4,300 個字元、1 MiB 的掃描文字、128 KiB 的解碼後酬載。
原始的 CBOR(或 PSBT)位元組會一直附在解碼後的請求上。就在簽名之前,引擎會再次解碼它們,如果與審核過的內容不再相符,就會拒絕簽名。
審核畫面顯示真實的位元組
引擎會自行解析交易或訊息;它從不信任連網錢包所提供的摘要。例如:
- Bitcoin:每個輸入與輸出及其金額和地址、手續費,以及哪個輸出是找零。只有在簽名器能以自己的公鑰重新衍生出該輸出的腳本時,該輸出才算找零。僅憑 PSBT 標籤永遠無法讓一個輸出成為「找零」。
- EVM:網路、nonce、手續費、收款人、原生代幣數量,以及解碼後的呼叫(ERC-20/721/1155 轉帳與授權、Permit、Permit2、Safe 交易等)。Spender 與 operator 地址會與內建的已知公開合約清單比對;未知的 spender 會提高風險等級。
- TRON:合約類型、金額、TRC-20/721 呼叫、fee limit、權限 ID。
- Solana:所有它認得的指令(System、SPL Token、Token-2022、ATA、Compute Budget、Memo、Stake 與 NFT 程式)、fee payer 與簽名者。
每個請求都會得到兩個獨立的標籤:
| 解碼 | 風險 |
|---|---|
| 完全解碼 · 部分解碼 · 不透明 | 一般 · 警告 · 高 |
一個有效但未完全解碼的請求(例如未知的合約呼叫)仍然可以簽名,但前提是使用者必須 針對該請求 明確確認風險。沒有任何會持續開啟的「盲簽」設定。格式錯誤的位元組、不支援的交易類型以及互相衝突的網路資料會被直接拒絕,且無法強制略過。
除特別註明外,以下問題都位於兩款 App 共用的引擎中。請參閱安全審查。
- 風險確認(iPhone 上為 BTS-OP5-01,Android 上為 BTS-12,低)。 完全解碼的高風險請求,例如無上限授權或
setApprovalForAll,同樣需要明確確認,但這條規則由 App 的介面強制執行(「簽名」按鈕保持停用);引擎只對部分解碼與不透明的請求強制執行。無法透過 QR 碼繞過。 - Solana 摘要(BTS-07,中)。 與一筆極小轉帳一起送出的權限變更、授權委託或不透明指令,會被摘要顯示為那筆轉帳。在 iPhone 1.0.0 上,銷毀也可能以同樣方式被掩蓋。警告與風險確認仍然保留。
- 比特幣找零(BTS-08,中)。 錢包自身單簽設定下任意索引上的輸出都會被視為找零,包括觀察錢包永遠不會掃描到的索引。
- EVM 與 TRON 摘要(BTS-09,低至中)。 對於未知合約呼叫,保存的摘要不包含隨呼叫送出的原生幣金額;審核卡片會顯示它。
比對正確的錢包
使用者從不選擇由哪個錢包簽名。引擎會將請求與每個本機錢包的 公開 資料比對,且只接受恰好一個相符的結果:
| 鏈 | 使用的依據 |
|---|---|
| Bitcoin | bip32Derivation 指紋與路徑,並對照輸入的實際腳本檢查。若無衍生資料,只會嘗試每個單簽帳戶的 /0/0。 |
| EVM | 衍生路徑(+ 主指紋)和/或地址。若無路徑,只會比對索引 0。 |
| TRON | 衍生路徑(任意索引),或與索引 0–99 比對的地址。 |
| Solana | 三個預設組合金鑰之一,且它也必須佔據訊息中的一個必要簽名者位置。 |
找不到相符項、缺少簽名者、比對結果不明確(有兩個錢包都符合)以及錢包資料不完整,都是各自不同的錯誤。簽名器從不逐一嘗試每個錢包的種子。
比對結果是一份不可變的 計畫,它綁定了 canonical 請求雜湊、原始位元組、確切的簽名位元組,以及目標金鑰與輸入。輸入密碼後,引擎會在接觸私鑰之前重新衍生金鑰、重建公開資料、重新執行比對,並比較完整的計畫。
務必包含衍生資料:PSBT 中的 bip32Derivation,以及 eth-、tron- 與 sol-sign-request 中的路徑與指紋。具備完整簽名者資料的請求能立即比對成功;沒有這些資料的請求會退回只比對索引 0,用於其他帳戶時就可能失敗。
將簽名與請求綁定
- 引擎會對整個 canonical 請求計算雜湊、簽名、驗證自己的簽名,並將結果連同原始請求雜湊一起傳回。如果簽名期間使用者離開 App,或新的請求取代了舊請求,延遲產生的結果會被捨棄。
- EVM、TRON 與 Solana 的回應會原樣帶回請求 ID,且簽名涵蓋的正是審核過的確切位元組。Bitcoin 回應會傳回加入簽名後的同一個 PSBT;其他所有欄位都必須保持不變。
- 一個 PSBT 可能需要多個本機錢包(例如同一支手機上有兩把金鑰的多重簽名)。每個錢包都是一項獨立的工作,各自需要密碼,而部分簽名會在各工作之間保留。
1.0.0 版的兩次安全審查都檢查了這整個流程。Opus 5 審查透過實際執行確認:遭竄改的計畫會被拒絕,且 Release 建置中唯一的簽名進入點會經過上述所有檢查。
離線無法涵蓋的範圍
當審核畫面無法得知某些資訊時,會明確說明:代幣合約的行為、目前的餘額與授權額度、TRON 多重簽名成員是否仍獲授權、Solana blockhash 是否仍然有效,或 Blur Merkle root 實際承諾的內容。你的錢包處於連網狀態,更適合在產生 QR Code 之前顯示這些背景資訊。