APK Signature Scheme v4

Android 11 รองรับรูปแบบการลงนามที่เข้ากันได้กับสตรีมมิ่งด้วย APK Signature Scheme v4 ลายเซ็น v4 อิงตามแผนผังแฮชของ Merkle ที่คำนวณจากไบต์ทั้งหมดของ APK มันเป็นไปตามโครงสร้างของแผนผังแฮช fs-verity ทุกประการ (เช่น การเติมเกลือเป็นศูนย์ และการเติมบล็อกสุดท้ายเป็นศูนย์) Android 11 เก็บลายเซ็นไว้ในไฟล์แยกต่างหาก <apk name>.apk.idsig ลายเซ็น v4 ต้องใช้ลายเซ็น v2 หรือ v3 เสริม

รูปแบบไฟล์

ช่องตัวเลขทั้งหมดอยู่ในรูปเอนเดียนเล็กๆ ฟิลด์ทั้งหมดใช้จำนวนไบต์ตาม 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;
};
  1. merkle_tree คือ แผนผัง Merkle ทั้งหมด ของ APK ซึ่งคำนวณตามที่อธิบายไว้ในเอกสารประกอบ fs-verity

ผู้ผลิตและผู้บริโภค

เครื่องมือ apksigner Android SDK จะสร้างไฟล์ลายเซ็น v4 หากคุณเรียกใช้ด้วยพารามิเตอร์เริ่มต้น การลงนาม v4 สามารถปิดใช้งานได้ในลักษณะเดียวกับแผนการลงนามอื่นๆ นอกจากนี้ยังสามารถตรวจสอบได้ว่าลายเซ็น v4 นั้นถูกต้องหรือไม่

adb คาดว่าไฟล์ .apk.idsig จะปรากฏถัดจาก .apk เมื่อรันคำสั่ง adb install --incremental
นอกจากนี้ยังจะใช้ไฟล์ .idsig เพื่อลองติดตั้งแบบเพิ่มหน่วยตามค่าเริ่มต้น และจะกลับไปใช้การติดตั้งปกติหากขาดหายไปหรือไม่ถูกต้อง

เมื่อสร้างเซสชันการติดตั้ง API การติดตั้งสตรีมมิ่งใหม่ใน PackageInstaller จะยอมรับลายเซ็น v4 ที่แยกออก มาเป็นอาร์กิวเมนต์แยกต่างหากเมื่อเพิ่มไฟล์ลงในเซสชัน ณ จุดนี้ signing_info จะถูกส่งผ่านไปยัง incfs เป็นหยดทั้งหมด Incfs แยกแฮชรูตออกจากหยด

เมื่อเซสชันการติดตั้งกำลังถูกคอมมิต PackageManagerService จะทำ ioctl เพื่อดึงข้อมูล signing_info blob จาก incfs แยกวิเคราะห์และตรวจสอบลายเซ็น

ส่วนประกอบ Data Loader ที่เพิ่มขึ้นคาดว่าจะสตรีมส่วนแผนผัง Merkle ของลายเซ็นผ่าน API ดั้งเดิมของตัวโหลดข้อมูล
คำสั่ง package service shell install-incremental ยอมรับไฟล์ลายเซ็นต์ v4 ที่แยกออกมาซึ่งเข้ารหัสเป็น base64 เป็นพารามิเตอร์สำหรับไฟล์แต่ละไฟล์ที่เพิ่ม จะต้องส่งต้นไม้ Merkle ที่เกี่ยวข้องไปยัง stdin ของคำสั่ง

apk_digest

apk_digest เป็นเนื้อหาย่อยแรกที่มีอยู่ตามลำดับ:

  1. V3, บล็อก 1MB, SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512)
  2. V3, บล็อก 4KB, SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256)
  3. V3, บล็อก 1MB, SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256)
  4. V2, SHA2-512,
  5. V2, SHA2-256.

ดู ลำดับคำนำหน้าความยาวของลายเซ็นที่นำหน้าความยาว ใน APK Signature Scheme v3

กระบวนการตรวจสอบ APK เวอร์ชัน 4.0
รูปที่ 1 : กระบวนการตรวจสอบ APK v4

การตรวจสอบและการทดสอบ

ตรวจสอบการใช้งานโดยใช้ Feature Unit Tests และ CTS

  • CtsIncrementalInstallHostTestCases
    • /android/cts/hostsidetests/increasealinstall

ทดสอบรูปแบบลายเซ็น

หากต้องการทดสอบรูปแบบลายเซ็น ให้ตั้งค่าสภาพแวดล้อมการพัฒนา และรันการทดสอบด้วยตนเองต่อไปนี้:

$ 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