Android 11 รองรับรูปแบบการเซ็นชื่อที่เข้ากันได้กับการสตรีมด้วย APK Signature Scheme v4 ลายเซ็น v4 อิงตามแผนผังแฮชของ Merkle ที่คำนวณจากไบต์ทั้งหมดของ APK มันเป็นไปตามโครงสร้างของต้นไม้แฮช fs-verity ทุกประการ (เช่น เติมเกลือให้ศูนย์และบล็อกสุดท้ายเป็นศูนย์) Android 11 เก็บลายเซ็นในไฟล์แยกต่างหาก <apk name>.apk.idsig
ลายเซ็น v4 ต้องมีลายเซ็น v2 หรือ v3 เสริม
รูปแบบไฟล์
ฟิลด์ตัวเลขทั้งหมดอยู่ใน 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
เป็นพารามิเตอร์ที่ใช้สำหรับการสร้าง hash tree + the root hash:
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 tree ทั้งหมด ของ APK ซึ่งคำนวณตามที่อธิบายไว้ในเอกสารประกอบ fs-verity
ผู้ผลิตและผู้บริโภค
เครื่องมือ apksigner
Android SDK ตอนนี้สร้างไฟล์ลายเซ็น v4 หากคุณเรียกใช้ด้วยพารามิเตอร์เริ่มต้น การลงนาม v4 สามารถปิดใช้งานได้เช่นเดียวกับรูปแบบการลงนามอื่นๆ นอกจากนี้ยังสามารถตรวจสอบได้ว่าลายเซ็น v4 นั้นถูกต้องหรือไม่
adb
คาดว่าไฟล์ .apk.idsig จะอยู่ถัดจาก .apk เมื่อรันคำสั่ง adb install --incremental
นอกจากนี้ยังจะใช้ไฟล์ .idsig เพื่อลองติดตั้งแบบเพิ่มหน่วยตามค่าเริ่มต้น และจะถอยกลับไปเป็นการติดตั้งปกติหากไฟล์นั้นหายไปหรือไม่ถูกต้อง
เมื่อมีการสร้างเซสชันการติดตั้ง API การติดตั้งการสตรีมใหม่ใน PackageInstaller
จะยอมรับลายเซ็น v4 ที่ ถอด เป็นอาร์กิวเมนต์แยกต่างหากเมื่อเพิ่มไฟล์ในเซสชัน ณ จุดนี้ signing_info
ถูกส่งผ่านไปยัง incfs ทั้งหมดเป็น Blob Incfs แยกแฮชรูตจากหยด
เมื่อมีการคอมมิตเซสชั่นการติดตั้ง PackageManagerService จะทำ ioctl เพื่อดึงข้อมูลการ sign_info blob จาก incfs แยกวิเคราะห์และตรวจสอบลายเซ็น
คอมโพเนนต์ตัวโหลดข้อมูลส่วนเพิ่มคาดว่าจะสตรีมส่วนทรี Merkle ของลายเซ็นผ่าน API ดั้งเดิมของตัวโหลดข้อมูล
คำสั่ง package
service shell install-incremental
ยอมรับไฟล์ลายเซ็น v4 ที่ถูกถอดออกมาซึ่งเข้ารหัสเป็น base64 เป็นพารามิเตอร์สำหรับแต่ละไฟล์ที่เพิ่ม ต้องส่ง Merkle tree ที่เกี่ยวข้องไปยัง stdin
ของคำสั่ง
apk_digest
apk_digest
เป็นไดเจสต์เนื้อหาแรกที่มีให้ตามลำดับ:
- V3, บล็อก 1MB, SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512),
- V3, บล็อก 4KB, SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256),
- V3, บล็อก 1MB, 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 จากโฟลเดอร์เครื่องมือสร้าง
เข้าสู่ระบบ
$ ./apksigner sign --ks debug.keystore game.apk
ติดตั้ง
$ ./adb install game.apk
การทดสอบเหล่านี้หาได้จากที่ไหน?
/android/cts/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java