סכימת חתימות APK v4

אנדרואיד 11 תומך בסכימת חתימה תואמת סטרימינג עם ערכת ה-APK Signature Scheme v4. חתימת ה-v4 מבוססת על עץ הגיבוב של Merkle המחושב על פני כל הבייטים של ה-APK. הוא עוקב אחר המבנה של עץ הגיבוב של fs-verity בדיוק (לדוגמה, ריפוד אפס את המלח ואפס ריפוד הבלוק האחרון). אנדרואיד 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 + 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 יש לבצע סדרה של הנתונים הבאים לכתם בינארי ולהעביר אותם לאלגוריתם החתימה/אימות בתור הנתונים החתומים :

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 מחלץ hash שורש מהבלוב.

כאשר הפעלת ההתקנה מתבצעת, PackageManagerService מבצע ioctl כדי לאחזר את הבלוק signing_info מ-incfs, מנתח אותו ומאמת את החתימה.

רכיב ה-Incremental Data Loader צפוי להזרים את חלק עץ Merkle של החתימה דרך ה-API המקורי של טוען הנתונים.
פקודת ה- package service shell install-incremental מקבלת את קובץ חתימת ה-v4 המופשט המקודד כ-base64 כפרמטר עבור כל קובץ שנוסף. יש לשלוח את עץ מרקל המתאים ל- 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 v4
איור 1 : תהליך אימות APK v4

אימות ובדיקה

אמת את היישום באמצעות בדיקות יחידת תכונות ו-CTS.

  • CtsIncrementalInstallHostTestCases
    • /android/cts/hostsidetests/incrementalinstall

בדיקת פורמט החתימה

כדי לבדוק את פורמט החתימה, הגדר סביבת פיתוח והפעל את הבדיקות הידניות הבאות:

$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest

בדיקת פורמט חתימה עם Android SDK (ADB ו-apksigner)

כדי לבדוק את פורמט החתימה עם Android SDK, הגדר סביבת פיתוח וודא שהשלמת את היישום של IncFS . לאחר מכן הבזק את ה-build על מכשיר פיזי או אמולטור יעד. עליך ליצור או להשיג 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