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 โค้ดจะต้องจัดรูปแบบข้อมูลต่อไปนี้เป็น Blob แบบไบนารี
และส่งไปยังอัลกอริทึมการลงนามและการยืนยันเป็นข้อมูลที่ลงนาม
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 adb ยังใช้ไฟล์ IDSIG
เพื่อลองติดตั้งแบบเพิ่มทีละรายการโดยค่าเริ่มต้น และจะกลับไปใช้การติดตั้งปกติหากไฟล์
ขาดหายไปหรือไม่ถูกต้อง
เมื่อสร้างเซสชันการติดตั้งแล้ว API การติดตั้งสตรีมมิงแบบใหม่
ใน PackageInstaller จะยอมรับลายเซ็น v4 ที่ตัดออก
เป็นอาร์กิวเมนต์แยกต่างหากเมื่อเพิ่มไฟล์ลงในเซสชัน
ในขั้นตอนนี้ ระบบจะส่ง signing_info ไปยัง IncFS เป็น
บล็อกทั้งหมด IncFS จะดึงแฮชรูทจาก Blob
เมื่อมีการคอมมิตเซสชันการติดตั้ง PackageManagerService จะioctlเรียกใช้เพื่อดึงข้อมูลออบเจ็กต์ขนาดใหญ่แบบไบนารี (Blob) signing_info จาก IncFS, แยกวิเคราะห์ และตรวจสอบลายเซ็น
คอมโพเนนต์โปรแกรมโหลดข้อมูลแบบเพิ่มจะสตรีมส่วนต้นไม้ Merkle
ของลายเซ็นผ่าน API ดั้งเดิมของโปรแกรมโหลดข้อมูล
packageคำสั่งเชลล์ของบริการ install-incremental
ยอมรับไฟล์ลายเซ็น v4 ที่ลบข้อมูลออกแล้วซึ่งเข้ารหัสเป็น Base64 เป็นพารามิเตอร์สำหรับแต่ละไฟล์
ที่เพิ่ม ต้องส่ง Merkle Tree ที่เกี่ยวข้องไปยัง stdin ของคำสั่ง
apk_digest
apk_digest คือสรุปเนื้อหาแรกที่พร้อมใช้งานตามลำดับต่อไปนี้
- V3, 1 MB block, SHA2-512 (
CONTENT_DIGEST_CHUNKED_SHA512) - V3, บล็อกขนาด 4 KB, 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
การตรวจสอบและการทดสอบ
กระบวนการตรวจสอบ APK v4 แสดงอยู่ในรูปต่อไปนี้

รูปที่ 1 กระบวนการตรวจสอบ APK เวอร์ชัน 4
ตรวจสอบการติดตั้งใช้งานโดยใช้การทดสอบหน่วยฟีเจอร์และ 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