Android 11 รองรับรูปแบบการรับรองที่เข้ากันได้กับการสตรีมด้วย APK Signature Scheme v4 ลายเซ็น v4 อิงตาม Merkle Hash Tree ที่คำนวณจากไบต์ทั้งหมดของ APK โดยเป็นไปตามโครงสร้างของต้นไม้แฮช fs-verity ทุกประการ (เช่น การเติมค่า 0 ลงท้าย Salt และการเติมค่า 0 ลงท้ายบล็อกสุดท้าย) Android 11 จะจัดเก็บลายเซ็นในไฟล์แยกต่างหาก <apk name>.apk.idsig
ลายเซ็น v4 ต้องใช้ลายเซ็น v2 หรือ v3 เสริม
รูปแบบไฟล์
ฟิลด์ตัวเลขทั้งหมดอยู่ในรูปแบบ Little Endian ฟิลด์ทั้งหมดใช้จำนวนไบต์เท่ากับ sizeof()
ของฟิลด์นั้นๆ โดยไม่มีการเพิ่มการเติมหรือการจัดแนวโดยนัย
ด้านล่างนี้คือโครงสร้างตัวช่วยเพื่อลดความซับซ้อนของคําจํากัดความ
template <class SizeT> struct sized_bytes { SizeT size; byte bytes[size]; };
เนื้อหาไฟล์หลัก
struct V4Signature { int32 version; // only version 2 is supported as of now sized_bytes<int32> hashing_info; sized_bytes<int32> signing_info; sized_bytes<int32> merkle_tree; // optional };
hashing_info
คือพารามิเตอร์ที่ใช้ในการสร้างต้นไม้แฮช + แฮชรูท
struct hashing_info.bytes { int32 hash_algorithm; // only 1 == SHA256 supported int8 log2_blocksize; // only 12 (block size 4096) supported now sized_bytes<int32> salt; // used exactly as in fs-verity, 32 bytes max sized_bytes<int32> raw_root_hash; // salted digest of the first Merkle tree page };
signing_info
คือโครงสร้างต่อไปนี้
struct signing_info.bytes { sized_bytes<int32> apk_digest; // used to match with the corresponding APK sized_bytes<int32> x509_certificate; // ASN.1 DER form sized_bytes<int32> additional_data; // a free-form binary data blob sized_bytes<int32> public_key; // ASN.1 DER, must match the x509_certificate int32 signature_algorithm_id; // see the APK v2 doc for the list sized_bytes<int32> signature; };
apk_digest
นำมาจากบล็อกการรับรอง v3 ของ APK หรือหากไม่มี ให้นำมาจากบล็อก v2 (ดู apk_digest)
หากต้องการสร้างและยืนยัน signature
โค้ดต้องจัดรูปแบบข้อมูลต่อไปนี้เป็นบล็อกไบนารีและส่งไปยังอัลกอริทึมการลงนาม / การยืนยันเป็น ข้อมูลที่ลงนาม
struct V4DataForSigning { int32 size; int64 file_size; // the size of the file that's been hashed. hashing_info.hash_algorithm; hashing_info.log2_blocksize; hashing_info.salt; hashing_info.raw_root_hash; signing_info.apk_digest; signing_info.x509_certificate; signing_info.additional_data; };
merkle_tree
คือต้นไม้ Merkle ทั้งหมดของ APK ซึ่งคำนวณตามที่อธิบายไว้ในเอกสารประกอบ fs-verity
ผู้ผลิตและผู้บริโภค
apksigner
ตอนนี้เครื่องมือ Android SDK จะสร้างไฟล์ลายเซ็น v4 หากคุณเรียกใช้ด้วยพารามิเตอร์เริ่มต้น คุณสามารถปิดใช้การลงนาม v4 ได้เช่นเดียวกับรูปแบบการลงนามอื่นๆ รวมถึงยังตรวจสอบได้ด้วยว่าลายเซ็น v4 ถูกต้องหรือไม่
adb
จะคาดหวังว่าจะมีไฟล์ .apk.idsig อยู่ข้างไฟล์ .apk เมื่อเรียกใช้คำสั่ง adb install --incremental
นอกจากนี้ ไฟล์ดังกล่าวยังใช้เพื่อพยายามติดตั้งแบบเพิ่มทีละรายการโดยค่าเริ่มต้น และจะเปลี่ยนไปใช้การติดตั้งแบบปกติหากไฟล์ไม่อยู่หรือไม่ถูกต้อง
เมื่อสร้างเซสชันการติดตั้งแล้ว API การติดตั้งสตรีมมิงใหม่ใน PackageInstaller
จะยอมรับลายเซ็น v4 ที่ลบออกแล้วเป็นอาร์กิวเมนต์แยกต่างหากเมื่อเพิ่มไฟล์ลงในเซสชัน
เมื่อถึงจุดนี้ ระบบจะส่ง signing_info
ไปยัง incfs เป็นบล็อกข้อมูลทั้งหมด Incfs จะดึงข้อมูลแฮชรูทจาก Blob
เมื่อมีการคอมมิตเซสชันการติดตั้ง PackageManagerService จะดำเนินการ ioctl เพื่อดึงข้อมูล signing_info
blob จาก incfs, แยกวิเคราะห์ และยืนยันลายเซ็น
คาดว่าคอมโพเนนต์เครื่องมือโหลดข้อมูลส่วนเพิ่มจะสตรีม Merkle Tree ของลายเซ็นผ่าน API ของเครื่องมือโหลดข้อมูล
package
คำสั่งเชลล์ของบริการ install-incremental
ยอมรับไฟล์ลายเซ็น v4 ที่ลบข้อมูลแล้วซึ่งเข้ารหัสเป็น Base64 เป็นพารามิเตอร์สำหรับไฟล์ที่เพิ่มแต่ละไฟล์ คุณต้องส่ง Merkle Tree ที่เกี่ยวข้องไปยัง stdin
ของคําสั่ง
apk_digest
apk_digest
คือข้อมูลสรุปเนื้อหารายการแรกตามลำดับต่อไปนี้
- V3, บล็อก 1 MB, SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512)
- V3, บล็อก 4KB, SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256)
- V3, บล็อก 1 MB, SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256)
- V2, SHA2-512,
- V2, SHA2-256
ดูลำดับลายเซ็นที่มีความยาวนำหน้าใน APK Signature Scheme v3

การตรวจสอบและการทดสอบ
ตรวจสอบการติดตั้งใช้งานโดยใช้การทดสอบหน่วยของฟีเจอร์และ CTS
CtsIncrementalInstallHostTestCases
- /android/cts/hostsidetests/incrementalinstall
ทดสอบรูปแบบลายเซ็น
หากต้องการทดสอบรูปแบบลายเซ็น ให้ตั้งค่าสภาพแวดล้อมการพัฒนาและทำการทดสอบด้วยตนเองต่อไปนี้
$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest
ทดสอบรูปแบบลายเซ็นด้วย Android SDK (ADB และ apksigner)
หากต้องการทดสอบรูปแบบลายเซ็นด้วย Android SDK ให้ตั้งค่าสภาพแวดล้อมการพัฒนา และตรวจสอบว่าคุณได้ติดตั้งใช้งาน IncFS แล้ว จากนั้นแฟลชบิลด์ในอุปกรณ์จริงหรือโปรแกรมจำลองเป้าหมาย คุณต้องสร้างหรือรับ APK ที่มีอยู่ แล้วสร้างคีย์การรับรองข้อบกพร่อง สุดท้าย ให้ลงนามและติดตั้ง APK ด้วยรูปแบบลายเซ็น v4 จากโฟลเดอร์ build-tools
ลงชื่อ
$ ./apksigner sign --ks debug.keystore game.apk
ติดตั้งเลย
$ ./adb install game.apk
ฉันจะดูการทดสอบเหล่านี้ได้จากที่ใด
/android/cts/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java