可重現建置在已發布的原始碼與釋出的二進位檔之間建立了可驗證的連結。我們目前的可重現建置涵蓋範圍適用於 Android F-Droid 版本。我們計畫將此涵蓋範圍擴展到更多 Android 與 iOS 發布管道。
Android
F-Droid
Gem Wallet 使用獨立的 F-Droid 建置基礎設施來重新建置 F-Droid APK,並在發布前加以驗證。
驗證模型
Gem Wallet 為每個版本發布經過簽署的 F-Droid APK。與此同時,F-Droid 建置伺服器在乾淨的環境中執行公開的建置配方:
- F-Droid 中繼資料指定確切的 Git 提交與 Android NDK 版本。
- F-Droid 從公開的 Gem Wallet 儲存庫簽出該提交。
- 公開的可重現建置腳本會安裝鎖定版本的原生工具鏈並執行
:app:assembleFdroidRelease。 - 建置會產生未簽署的 APK。F-Droid 下載對應的開發者簽署 APK,並確認其簽署憑證指紋與
AllowedAPKSigningKeys中宣告的一致。 - F-Droid 將 APK 簽章複製到重新建置的產物上並加以驗證。Android APK Signature Scheme v2/v3 簽章涵蓋簽章區塊以外的完整 APK,因此驗證成功的前提是重新建置的 APK 酬載必須與 Gem Wallet 發布版本逐位元組一致。
- 只有在驗證成功時,F-Droid 才會發布開發者簽署的 APK。無法重現的版本不會被發布。
確定性建置控制
Gem Wallet 包含 Rust 原生函式庫,這使得建置輸出對編譯器、連結器、NDK、主機平台與最佳化工具的差異非常敏感。F-Droid 建置透過以下方式控制這些輸入:
- 在
android/reproducible/versions.sh中鎖定 Rust 工具鏈與cargo-ndk的版本; - 使用
--locked安裝cargo-ndk,而應用程式的 Rust 相依套件則由已提交的Cargo.lock解析; - 在 Android 專案與 F-Droid 中繼資料中同時鎖定確切的 Android NDK 修訂版本;
- 在 Linux
x86_64主機上建置,並明確指定 NDK 連結器與封存工具的路徑; - 將原生 APK 目標限制為
armeabi-v7a與arm64-v8a,與x86_64建置主機無關; - 使用專用的
fdroid產品通道,不包含 Google 推播與評分模組; - 使用
-dontoptimize停用 R8 最佳化,以避免非確定性的 DEX 輸出與對應識別碼; - 執行 Gradle 時不使用常駐程式或組態快取,並在發布建置前清除轉換快取。
確切的原始碼提交、建置指令、輸出路徑、NDK 修訂版本、上游 APK URL 與允許的簽署憑證都公開於 F-Droid 中繼資料。用於設定 Rust、Cargo、NDK 工具鏈與 Gradle 的腳本與應用程式原始碼一同維護在 android/reproducible 目錄下。
安全特性與限制
F-Droid 驗證成功表明,Gem Wallet 發布的已簽署 APK 可以從宣告的原始碼提交與建置配方重現。重新建置在 Gem Wallet 基礎設施之外進行,降低了對我們發布管線作為單一信任點的依賴。
可重現性並不能證明原始碼沒有漏洞、每個相依套件都值得信任,或所選的編譯器工具鏈未遭入侵。這些風險需要在可重現建置之外,透過原始碼審查、相依性管控與工具鏈安全來因應。
建置狀態與已驗證的版本可在 Gem Wallet F-Droid 頁面查看。
Universal APK 與 Google Play
Gem Wallet 的 Universal APK 與 Google Play 版本目前尚未納入上述 F-Droid 驗證。針對這些 Android 發布管道的可重現建置支援已列入未來計畫。
iOS
App Store 版本目前尚無法重現。針對 iOS 的可重現建置支援以及對 App Store 二進位檔的獨立驗證已列入未來計畫。