תוכנית חתימות APK v3

אנדרואיד 9 תומך בסיבוב מקשי APK , מה שמאפשר לאפליקציות לשנות את מפתח החתימה שלהם כחלק מעדכון APK. כדי להפוך את הסיבוב למעשי, APKs חייבים לציין רמות אמון בין מפתח החתימה החדש והישן. כדי לתמוך בסיבוב המקשים, עדכנו את תכנית חתימת ה- APK מ- v2 ל- v3 כדי לאפשר שימוש במפתחות חדשים וישנים. V3 מוסיף מידע על גרסאות ה- SDK הנתמכות ומבנה הוכחת סיבוב לחסימת ה- APK.

חסימת חתימה APK

כדי לשמור על תאימות לאחור עם פורמט APK v1, חתימות APK של v2 ו- v3 נשמרות בתוך חסימת חתימה של APK, הממוקמת מיד לפני המדריך המרכזי של ZIP.

הפורמט של חסימת חתימה APK v3 זהה ל- v2 . חתימת ה- v3 של ה- APK נשמרת כצמד ערך מזהה עם מזהה 0xf05368c0.

תוכנית חתימה APK חוסמת v3

תוכנית v3 תוכננה להיות דומה מאוד לתכנית v2 . יש לו אותו פורמט כללי ותומך באותם מזהי אלגוריתם חתימה , גדלי מפתח ועיקולי EC.

עם זאת, תוכנית v3 מוסיפה מידע על גרסאות ה- SDK הנתמכות ועל מבנה ההוכחה לסיבוב.

פוּרמָט

תוכנית חתימת APK v3 0xf05368c0 מאוחסנת בתוך חסימת החתימה של APK תחת מזהה 0xf05368c0 .

הפורמט של חסימת APK חתימת v3 חוסם את זה של v2:

  • רצף קידומת אורך של signer קידומת אורך:
    • signed data קידומת אורך:
      • אורך ולפניו רצף של ולפניו אורך digests :
        • signature algorithm ID (4 בתים)
        • digest (קידומת אורך)
      • רצף קידומת אורך של certificates X.509:
        • אורך ולפניו X.509 certificate (טופס DER ASN.1)
      • minSDK ( minSDK ) - יש להתעלם minSDK זה אם גרסת הפלטפורמה נמוכה ממספר זה.
      • maxSDK ( maxSDK ) - יש להתעלם maxSDK זה אם גרסת הפלטפורמה היא מעל למספר זה.
      • רצף עם קידומת אורך של additional attributes קידומת אורך:
        • ID (uint32)
        • value (אורך משתנה: אורך התכונה הנוספת - 4 בתים)
        • ID - 0x3ba06f8c
        • value - הוכחת סיבוב
    • minSDK ( minSDK ) - כפילות של ערך minSDK בקטע נתונים חתומים - משמש לדילוג על אימות של חתימה זו אם הפלטפורמה הנוכחית אינה בטווח. חייב להתאים לערך הנתונים החתום.
    • maxSDK ( maxSDK ) - כפילות של ערך maxSDK במקטע הנתונים החתומים - משמש לדילוג על אימות של חתימה זו אם הפלטפורמה הנוכחית אינה בטווח. חייב להתאים לערך הנתונים החתום.
    • רצף קידומת אורך של signatures קידומת אורך:
      • signature algorithm ID (uint32)
      • signature קידומת אורך על פני signed data
    • public key קידומת אורך (SubjectPublicKeyInfo, טופס DER ASN.1)

הוכחות של סיבוב וסמכות עצמית-ישנה

מבנה הוכחת הסיבוב מאפשר לאפליקציות לסובב את תעודת החתימה שלהם מבלי להיחסם באפליקציות אחרות איתן הם מתקשרים. לשם כך, חתימות האפליקציה מכילות שתי פיסות נתונים חדשות:

  • טענה לצדדים שלישיים כי ניתן לסמוך על תעודת החתימה של האפליקציה בכל מקום שאפשר לסמוך על קודמיו
  • סרטי החתימה הישנים של האפליקציה שהאפליקציה עצמה עדיין סומכת עליהם

מאפיין הוכחת הסיבוב במקטע הנתונים החתומים מורכב מרשימה המקושרת יחידה, כאשר כל צומת מכיל אישור חתימה המשמש לחתימה על גרסאות קודמות של האפליקציה. תכונה זו נועדה להכיל את מבני הנתונים ההוכחתיים לסיבוב רעיוני ואמין-ישן. הרשימה מסודרת לפי גרסה עם תעודת החתימה העתיקה ביותר המתאימה לצומת הבסיס. מבנה הנתונים של הוכחת סיבוב נבנה על ידי כך שהאישור בכל צומת יחתום על הבא ברשימה, ובכך ישתלב כל מפתח חדש עם ראיות לכך שהוא אמור להיות אמון כמו המפתח / ים הישנים.

מבנה הנתונים המהימן העצמי-ישן- certs בנוי על ידי הוספת דגלים לכל צומת המציין את חברותו ואת המאפיינים שלו בערכה. לדוגמה, ייתכן שיש דגל המציין כי אישור החתימה בצומת נתון מהימן לקבלת הרשאות חתימת Android. דגל זה מאפשר לאפליקציות אחרות עליהן חתום האישור הישן עדיין לקבל הרשאת חתימה המוגדרת על ידי אפליקציה החתומה באישור החתימה החדש. מכיוון שכל מאפיין הוכחת הסיבוב נמצא בקטע הנתונים החתום בשדה signer v3, הוא מוגן על ידי המפתח המשמש לחתימת ה- apk המכיל.

פורמט זה מונע מספר מפתחות חתימה והתכנסות של אישורי חתימה קדומים שונים לאחד (צמתים מתחילים מרובים לכיור משותף).

פוּרמָט

הוכחת הסיבוב נשמרת בתוך חסימת APK חתימת 0x3ba06f8c v3 תחת מזהה 0x3ba06f8c . הפורמט שלה הוא:

  • רצף קידומת אורך של levels קידומת אורך:
    • signed data קידומת אורך (לפי תעודה קודמת - אם קיימים)
      • אורך ולפניו X.509 certificate (טופס DER ASN.1)
      • signature algorithm ID (uint32) - אלגוריתם ששימש cert ברמה הקודמת
    • flags (uint32) - דגלים המציינים אם תעודה זו צריכה להיות במבנה האמון העצמי-ישן-סרטי או לאילו פעולות.
    • signature algorithm ID (uint32) - חייב להתאים לזה שמופיע במקטע הנתונים החתום ברמה הבאה.
    • signature קידומת אורך על פני signed data לעיל

תעודות מרובות

אנדרואיד מתייחסת כיום ל- APK שנחתם במספר אישורים כבעל זהות חתימה ייחודית הנפרדת מהסרטים הכוללים. לפיכך, תכונת הוכחת הסיבוב במקטע הנתונים החתומים מהווה גרף א-מחזורי מכוון, שניתן לראותו טוב יותר כרשימה המקושרת יחידה, כאשר כל קבוצה של חותמים לגרסה נתונה מייצגת צומת אחד. זה מוסיף מורכבות נוספת למבנה הוכחת הסיבוב (גרסת ריבוי חתימות בהמשך). בפרט, הזמנה הופכת לדאגה. יתרה מכך, לא ניתן עוד לחתום על APKs באופן עצמאי, מכיוון שמבנה הוכחת הסיבוב חייב לכלול את אישורי החתימה הישנים על חתימת ה- certs החדשה, במקום לחתום עליהם אחד אחד. לדוגמא, APK חתום על ידי מפתח A המעוניין להיחתם על ידי שני מקשים B ו- C חדשים לא יכול היה שחותם B יכלול רק חתימה על ידי A או B, מכיוון שזו זהות חתימה שונה מזו B ו- C. זה היה אומר שעל החותמים לתאם לפני שבונים מבנה כזה.

מאפיין הוכחה לסיבוב של מספר חותמים

  • רצף של קידומת אורך של sets קידומת אורך:
    • signed data (לפי קבוצה קודמת - אם קיימים)
      • רצף certificates של קידומת אורך
        • אורך ולפניו X.509 certificate (טופס DER ASN.1)
      • רצף של signature algorithm IDs (uint32) - אחד לכל אישור מהקבוצה הקודמת, באותו סדר.
    • flags (uint32) - דגלים המציינים אם קבוצה זו של certs צריכה להיות במבנה האמין-ישן-certs או לאילו פעולות.
    • רצף קידומת אורך של signatures קידומת אורך:
      • signature algorithm ID (uint32) - חייב להתאים לזה שמופיע במקטע הנתונים החתומים
      • signature קידומת אורך על פני signed data לעיל

אבות קדומים רבים במבנה הוכחת סיבוב

ערכת v3 גם לא מטפלת בשני מקשים שונים המסתובבים לאותו מפתח חתימה עבור אותה אפליקציה. זה שונה מהמקרה של רכישה, כאשר החברה הרוכשת תרצה להעביר את האפליקציה הנרכשת להשתמש במפתח החתימה שלה כדי לשתף הרשאות. הרכישה נתפסת כמקרה שימוש נתמך מכיוון שהאפליקציה החדשה תובחן באמצעות שם החבילה שלה ותוכל להכיל מבנה הוכחה לסיבוב משלה. המקרה הלא נתמך, של אותה אפליקציה שיש לה שני מסלולים שונים להגיע לאותה תעודה, שובר הרבה מההנחות שנעשו בתכנון סיבוב המפתח.

אימות

ב- Android 9 ואילך, ניתן לאמת APKs על פי ערכת חתימת APK v3, ערכת v2 או ערכת v1. פלטפורמות ישנות יותר מתעלמות מחתימות v3 ומנסות לאמת חתימות v2, ואז v1.

תהליך אימות חתימת APK

איור 1. תהליך אימות חתימת APK

אימות APK חתימת תוכנה v3

  1. אתר את חסימת החתימה של APK וודא כי:
    1. שני שדות גודל של חסימת חתימת APK מכילים את אותו הערך.
    2. אחרי המדריך המרכזי של ZIP, מיד אחריו ה- ZIP סוף הרשומה של המדריך המרכזי.
    3. אחרי סיום ה- ZIP של הספריה המרכזית אין נתונים נוספים.
  2. אתר את חסימת APK חתימת v3 הראשונה ב- Block חתימת APK. אם חסום v3 קיים, המשך לשלב 3. אחרת, חזור לאימות ה- APK באמצעות ערכת v2 .
  3. עבור כל signer ב- APK Signature Scheme v3 Block עם גרסת SDK מינימלית ומקסימלית הנמצאת בטווח הפלטפורמה הנוכחית:
    1. בחר את signature algorithm ID הנתמך החזק ביותר signatures . הזמנת הכוח תלויה בכל גרסת יישום / פלטפורמה.
    2. בדוק את מתאים signature מן signatures נגד signed data באמצעות public key . (כעת ניתן לנתח signed data .)
    3. ודא שגרסאות ה- SDK המינימליות והמקסימליות בנתונים החתומים תואמות את אלו שצוינו עבור signer .
    4. ודא שהרשימה המסודרת של מזהי אלגוריתם חתימות digests signatures זהה. (זה כדי למנוע הפשטה / הוספה של חתימות).
    5. חישוב העיכול של תכני APK באמצעות אותו אלגוריתם עיכול כמו אלגוריתם העיכול שמשמש את אלגוריתם החתימה.
    6. ודא כי העיכול המחושב זהה digest המתאים digests .
    7. ודא ש- SubjectPublicKeyInfo של certificate הראשון של certificates זהה public key .
    8. אם קיימת תכונת הוכחת סיבוב עבור signer ודא שה- struct חוקי signer זה הוא האישור האחרון ברשימה.
  4. האימות מצליח אם בדיוק נמצא signer אחד בטווח הפלטפורמה הנוכחית ושלב 3 הצליח עבור אותו signer .

מַתַן תוֹקֵף

כדי לבדוק שהמכשיר שלך תומך ב- v3 כראוי, הפעל את מבחני CTS PkgInstallSignatureVerificationTest.java ב- cts/hostsidetests/appsecurity/src/android/appsecurity/cts/ .