บิลด์ที่ทำซ้ำได้สร้างความเชื่อมโยงที่ตรวจสอบได้ระหว่างซอร์สโค้ดที่เผยแพร่กับไบนารีของรุ่นที่ปล่อยออกมา ปัจจุบันขอบเขตบิลด์ที่ทำซ้ำได้ของเราครอบคลุมรุ่น F-Droid บน Android เราตั้งใจจะขยายขอบเขตนี้ไปยังช่องทางการเผยแพร่อื่น ๆ ทั้งบน 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 ที่เป็นสาธารณะ
- สคริปต์บิลด์ที่ทำซ้ำได้ ซึ่งเป็นสาธารณะจะติดตั้ง toolchain แบบเนทีฟที่ตรึงเวอร์ชันไว้ และรัน
:app:assembleFdroidRelease - การบิลด์จะได้ APK ที่ยังไม่ได้ลงลายเซ็น F-Droid จะดาวน์โหลด APK ที่นักพัฒนาลงลายเซ็นไว้ซึ่งตรงกัน และยืนยันว่าถูกลงลายเซ็นด้วยลายนิ้วมือใบรับรอง (certificate fingerprint) ที่ประกาศไว้ใน
AllowedAPKSigningKeys - F-Droid คัดลอกลายเซ็น APK ไปยังอาร์ติแฟกต์ที่บิลด์ขึ้นใหม่และตรวจสอบลายเซ็นนั้น ลายเซ็นตามมาตรฐาน Android APK Signature Scheme v2/v3 ครอบคลุม APK ทั้งหมดนอกบล็อกลายเซ็น ดังนั้นการตรวจสอบจะสำเร็จได้ก็ต่อเมื่อเพย์โหลดของ APK ที่บิลด์ขึ้นใหม่ตรงกับรุ่นของ Gem Wallet แบบไบต์ต่อไบต์
- F-Droid เผยแพร่ APK ที่นักพัฒนาลงลายเซ็นไว้เฉพาะเมื่อการตรวจสอบสำเร็จเท่านั้น รุ่นที่ไม่สามารถทำซ้ำได้จะไม่ถูกเผยแพร่
การควบคุมบิลด์แบบดีเทอร์มินิสติก
Gem Wallet มีไลบรารีเนทีฟที่เขียนด้วย Rust ทำให้ผลลัพธ์อ่อนไหวต่อความแตกต่างของคอมไพเลอร์ ลิงเกอร์ NDK แพลตฟอร์มโฮสต์ และออปติไมเซอร์ การบิลด์ของ F-Droid ควบคุมอินพุตเหล่านี้โดย
- ตรึงเวอร์ชันของ Rust toolchain และ
cargo-ndkไว้ในandroid/reproducible/versions.sh - ติดตั้ง
cargo-ndkด้วย--lockedขณะที่ dependency ภาษา Rust ของแอปพลิเคชันถูกกำหนดโดยCargo.lockที่คอมมิตไว้ - ตรึงรุ่นของ Android NDK ที่แน่นอนทั้งในโปรเจกต์ Android และในข้อมูลเมตาของ F-Droid
- บิลด์บนโฮสต์ Linux
x86_64พร้อมระบุพาธของลิงเกอร์และอาร์ไคเวอร์ของ NDK อย่างชัดเจน - จำกัดเป้าหมาย APK แบบเนทีฟไว้ที่
armeabi-v7aและarm64-v8aโดยไม่ขึ้นกับโฮสต์บิลด์x86_64 - ใช้ช่องทางผลิตภัณฑ์
fdroidโดยเฉพาะ ซึ่งไม่มีโมดูลพุชและรีวิวของ Google - ปิดการออปติไมซ์ของ R8 ด้วย
-dontoptimizeเพื่อป้องกันผลลัพธ์ DEX และตัวระบุ mapping ที่ไม่ดีเทอร์มินิสติก - รัน Gradle โดยไม่ใช้ daemon หรือ configuration cache และล้าง transformation cache ก่อนการบิลด์รุ่นเผยแพร่
คอมมิตต้นทางที่แน่นอน คำสั่งบิลด์ พาธของผลลัพธ์ รุ่นของ NDK, URL ของ APK ต้นทาง และใบรับรองการลงลายเซ็นที่อนุญาต เปิดเผยต่อสาธารณะในข้อมูลเมตาของ F-Droid ส่วนสคริปต์ที่กำหนดค่า Rust, Cargo, toolchain ของ NDK และ Gradle ได้รับการดูแลควบคู่กับซอร์สโค้ดของแอปพลิเคชันภายใต้ android/reproducible
คุณสมบัติด้านความปลอดภัยและข้อจำกัด
การตรวจสอบของ F-Droid ที่สำเร็จแสดงให้เห็นว่า APK ที่ลงลายเซ็นซึ่ง Gem Wallet เผยแพร่สามารถทำซ้ำได้จากคอมมิตต้นทางและสูตรบิลด์ที่ประกาศไว้ การบิลด์ใหม่นี้ดำเนินการนอกโครงสร้างพื้นฐานของ Gem Wallet จึงลดการพึ่งพาไปป์ไลน์การปล่อยรุ่นของเราในฐานะจุดความเชื่อถือเพียงจุดเดียว
ความสามารถในการทำซ้ำไม่ได้พิสูจน์ว่าซอร์สโค้ดปราศจากช่องโหว่ ว่า dependency ทุกตัวน่าเชื่อถือ หรือว่า toolchain ของคอมไพเลอร์ที่เลือกใช้ปลอดจากการถูกแทรกแซง ความเสี่ยงเหล่านี้ต้องอาศัยการตรวจสอบซอร์สโค้ด การควบคุม dependency และความปลอดภัยของ toolchain ควบคู่ไปกับบิลด์ที่ทำซ้ำได้
สถานะการบิลด์และรุ่นที่ผ่านการตรวจสอบดูได้ที่หน้า F-Droid ของ Gem Wallet
Universal APK และ Google Play
Universal APK ของ Gem Wallet และรุ่นบน Google Play ยังไม่อยู่ในขอบเขตการตรวจสอบของ F-Droid ตามที่อธิบายไว้ข้างต้น การรองรับบิลด์ที่ทำซ้ำได้สำหรับช่องทางการเผยแพร่ Android เหล่านี้อยู่ในแผนงานในอนาคต
iOS
รุ่นบน App Store ยังไม่สามารถทำซ้ำได้ในขณะนี้ การรองรับบิลด์ที่ทำซ้ำได้สำหรับ iOS และการตรวจสอบไบนารีบน App Store อย่างอิสระอยู่ในแผนงานในอนาคต