Android 11 תומך בסכמת חתימה תואמת לסטרימינג עם ה-APK
Signature Scheme v4. חתימת גרסה 4 מבוססת על עץ הגיבוב של Merkle
שמחושבת לכל הבייטים של ה-APK. הוא תואם בדיוק למבנה של עץ הגיבוב (hash) fs-verity (לדוגמה, אפס מרווח פנימי
את ה-salt ואת המרווח הפנימי בבלוק האחרון). החתימה נשמרת ב-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
הוא הפרמטרים שמשמשים לעץ הגיבוב (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, או אם לא, נוכחי, מחסימת גרסה 2 (מידע נוסף זמין בכתובת 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 יוצר עכשיו את קובץ החתימה בגרסה 4
אם משתמשים בו עם פרמטרים שמוגדרים כברירת מחדל. ניתן להשבית את חתימת V4 באותה הדרך
כמו הונאות החתימה האחרות. הוא יכול גם לוודא שחתימת V4
תקין.
adb
מצפה שקובץ ה- .APK.idsig יופיע לצד ה-APK כאשר:
הרצת הפקודה adb install --incremental
היא תשתמש גם בקובץ ה- .idsig כדי לנסות התקנה מצטברת באמצעות
כברירת מחדל, תתבצע חזרה להתקנה רגילה אם היא חסרה או
לא תקין.
כשיוצרים סשן התקנה, ממשק ה-API החדש להתקנת סטרימינג
ב-PackageInstaller
מקבל את הפסים
חתימת v4 כארגומנט נפרד כשמוסיפים קובץ לסשן.
בשלב הזה, signing_info
מועבר ל-incfs בתור
ב-blob. Incfs שולף את גיבוב השורש מה-blob.
כאשר מתבצעת מחויבות להפעלת ההתקנה, PackageManagerService מבצע ioctl לאחזור ה-blob של sign_info מ-incf, מנתח אותו ומאמת את החתימה.
הרכיב של הכלי לטעינת נתונים מצטבר צפוי להזרים את החלק של עץ Merkle
של החתימה דרך ה-API המקורי של טוען הנתונים.
פקודת מעטפת השירות install-incremental
של package
מקבל את קובץ החתימה v4 הפגום שמקודד כ-base64 כפרמטר
נוסף קובץ. צריך לשלוח את עץ ה-Merkle המתאים
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. לאחר מכן Flash ה-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