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

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

APK חסימת חסימה

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

ה- APK v3 חתימה בפורמט בלוק הוא זהה v2 . חתימת v3 של APK נשמרת כזוג ערך-מזהה עם מזהה 0xf05368c0.

חתימת APK חבילה v3

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

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

פוּרמָט

Scheme חתימת APK בלוק v3 מאוחסן בתוך APK חתימת בלוק תחת זהות 0xf05368c0 .

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

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

מבני הוכחת סיבוב ובטוח בעצמך

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

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

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

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

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

פוּרמָט

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

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

מספר תעודות

Android מתייחסת כיום ל- APK החתום עם מספר אישורים כבעל זהות חתימה ייחודית הנפרדת מהתעודות הכוללות. לפיכך, תכונת הוכחת הסיבוב שבקטע הנתונים החתומים יוצרת גרף אציקליים מכוון, שניתן לראותו בצורה טובה יותר כרשימה מקושרת, כאשר כל קבוצת חותמים לגרסה נתונה מייצגת צומת אחד. זה מוסיף מורכבות נוספת למבנה הוכחת הסיבוב (גרסה מרובת חותמים להלן). במיוחד ההזמנה הופכת לדאגה. יתרה מזאת, לא ניתן עוד לחתום על חבילות APK באופן עצמאי, מכיוון שבמבנה הוכחת הסיבוב חייבים אישורי החתימה הישנים לחתום על סט התעודות החדש, במקום לחתום עליהם אחד אחד. לדוגמה, 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 צריכה להיות struct המהימן העצמי בת-certs, ואשר פעילותה.
    • אורך ולפניו רצף של אורך ולפניו signatures :
      • signature algorithm ID (uint32) - חייב להתאים את אחד מסעיף הנתונים חתם
      • אורך ולפניו signature על מעל signed data

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

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

אימות

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

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

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

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

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

מַתַן תוֹקֵף

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