Android 13 תומך ב-APK signature scheme v3.1, שיפור של APK signature scheme v3 הקיים. ב-v3.1 Scheme נפתרו חלק מהבעיות המוכרות ב-APK Signature Scheme v3 שקשורות לרוטציה. בפרט, ערכת החתימה v3.1 תומכת בטירגוט של גרסת ה-SDK, שמאפשרת מעבר לגרסה מאוחרת יותר של הפלטפורמה.
בסכימת החתימה v3.1 נעשה שימוש במזהה בלוק שלא מזוהה ב-Android בגרסה 12 ומטה. לכן, הפלטפורמה מחילה את התנהגות החותם הבאה:
- במכשירים עם Android 13 ומעלה נעשה שימוש בחותם המסובב בבלוק v3.1.
- מכשירים שבהם פועלות גרסאות ישנות יותר של Android מתעלמים מהחתימה שהוחלפה ובמקום זאת משתמשים בחתימה המקורית בבלוק v3.
לא נדרשת פעולה נוספת באפליקציות שעדיין לא עברו סבב של חתימת האפליקציה. בכל פעם שהאפליקציות האלה בוחרות לבצע רוטציה, המערכת מחילה כברירת מחדל את סכמת החתימה v3.1.
בלוק חתימה v3.1
בלוק החתימה v3.1 מכיל את אותם נתונים כמו בלוק החתימה v3, אבל עם מזהה הבלוק החדש, החתימות האלה מזוהות רק במכשירים עם Android 13 ואילך. כך אפשר לסובב את מפתחות החתימה של האפליקציות בצורה בטוחה בלי לדאוג לגבי קובצי APK מרובי-יעדים, כי אפשר להשתמש בחותם המקורי כדי לחתום על ה-APK בבלוק החתימה v3, ובחותם שעבר רוטציה בבלוק החתימה v3.1. בנוסף, הפלטפורמה יכולה לעשות שימוש חוזר בכל קודי האימות הקיימים של בלוק החתימה v3, כשמאמתים חתימה v3.1.
כברירת מחדל, הספרייה apksig משתמשת בבלוק החתימה v3.1 בכל פעם שמסופקים מפתח מסובב ושושלת בהגדרת החתימה. אם minSdkVersion של האפליקציה הוא Android 12 ומטה, ונעשה שימוש במפתח שעבר רוטציה, צריך לציין גם את מפתח החתימה המקורי כדי שאפשר יהיה להשתמש בו לחתימה על ה-APK בבלוק החתימה v3. ההתנהגות הזו דומה להתנהגות הנוכחית שבה נדרש החותם המקורי אם קובץ ה-APK מטרגט גרסה מוקדמת יותר מ-Android 9.
כדי לתמוך בטירגוט של רוטציית מפתחות החל מגרסת SDK מסוימת, ספריית apksig חושפת ממשקי API חדשים שמאפשרים להגדיר גרסת SDK מינימלית לרוטציה. אם גרסת SDK נמוכה מ-Android 12 מוגדרת כגרסה המינימלית לתמיכה ברוטציה, נעשה שימוש בבלוק המקורי v3. בלוק החתימה v3.1 משמש רק בנוכחות של רוטציה, כאשר גרסת ה-SDK המינימלית לרוטציה מוגדרת ל-Android 12 ומעלה. בלוק החתימה v3 כולל מאפיין להגנה על הסרת גרסת ה-SDK המינימלית של הרוטציה.
| קובץ ה-APK כולל את שרשרת היוחסין | הערך של rotation-min-sdk-version | v3 signing block | בלוק חתימה v3.1 |
|---|---|---|---|
| לא | ברירת מחדל או כל ערך (מיוצג על ידי x בהמשך) | האפליקציה חתומה על ידי החותם המקורי, ומטרגטת ל-Android מגרסה 9 ומעלה | אין |
| כן | ברירת מחדל | חתום על ידי החותם המקורי, מטרגט ל-Android 9 עד 12L | חתימה עם חותם מסובב, טירגוט ל-Android מגרסה 12 ואילך |
| כן | x < 33 (Android 13) | חתימה עם חותם מסובב, טירגוט ל-Android מגרסה 9 ואילך | אין |
| כן | x >= 33 (Android 13) | חתימה באמצעות החותם המקורי, טירגוט ל-Android 9 – (x-1) | נחתם עם חותם מסובב, טירגוט x+ |
בעיות שקשורות לסיבוב
הבעיות הבאות שקשורות לסיבוב נפתרו בפלטפורמה:
תיקונים ב-Android 12
- הפלטפורמה תעניק הרשאת חתימה לאפליקציה שמבקשת אותה רק אם החותם הנוכחי של האפליקציה נמצא בשושלת החתימה, או שהוא החותם הנוכחי של האפליקציה השנייה. כך נמנעת הענקת הרשאת חתימה לאפליקציה שמבקשת אותה אם שתי האפליקציות פועלות לפי שיטות מומלצות של מפתחות חתימה ועוברות למפתחות חתימה שונים.
- אי אפשר להשתמש בתכונת החזרה לגרסה קודמת של APK בפלטפורמה כדי לחזור לגרסה קודמת של APK שבו בוצעה רוטציה של מפתח החתימה, אלא אם למפתח הקודם בשושלת החתימה הייתה יכולת החזרה לגרסה קודמת. אבל היכולת הזו מבטלת את המטרה של הרוטציה, כי היא מאפשרת לחתום על עדכון חדש של החבילה באמצעות מפתח החתימה הקודם ולחזור לגרסה קודמת של המפתח שעבר רוטציה.
- חבילת APK שנחתמה רק באמצעות המפתח שעבר רוטציה ועודכנה מאוחר יותר באמצעות חבילת APK שנחתמה באמצעות המפתח המקורי והמפתח שעבר רוטציה בשושלת, מציגה רק את המפתח שעבר רוטציה בשושלת במכשירים עם Android 11 ומגרסאות קודמות.
תיקונים ב-Android 11
- העדכון של
PackageManager#checkSignaturesלא בוצע בצורה תקינה, ולכן לא ניתן לבדוק את מפתחות החתימה המקוריים של שתי חבילות. הדבר גרם לכך שהמכשיר לא הצליח להפעיל את כלי המדידה באפליקציות שמשתמשות במפתח חתימה שעבר רוטציה, עם חבילת ה-APK של כלי המדידה שמשתמשת במפתח החתימה המקורי. - חבילות שנמצאות ב
sharedUserIdחולקות את שרשרת החתימה שלהן. בכל פעם שאפליקציה עם שושלת חתימה מעודכנת מותקנת או מתעדכנת ב-sharedUiserId, השושלת של האפליקציה הזו מחליפה את השושלת המשותפת שלsharedUserId(כלומר, אם שושלת החתימה של אפליקציה היא A -> B, ואפליקציה מתעדכנת ב-sharedUserIdעם השושלת B -> C, אז השושלת שלsharedUserIdתוחלף ב-B -> C). באופן דומה, לא ניתן לעדכן את היכולות של חותם קודם בשרשרת המקור, אלא אם שרשרת המקור של החתימה השתנתה.
שילוב גרסה 4
סכמת החתימה v4 משתמשת בהגדרת החתימה שסופקה ל-apksigner. במקרה של כמה הגדרות חתימה שסופקו לרוטציה, נעשה שימוש בהגדרת החתימה האחרונה שעברה רוטציה. לפני שהצגנו את גרסה 3.1, גרסה 3 כללה רק את הגדרת החתימה האחרונה שהוחלפה, ולכן גרסה 4 יכלה להשתמש בהגדרה הזו כמו שהיא. כך, סכמת החתימה של גרסה 4 יכלה לתמוך בהחלפה כי היא השתמשה במפתח החתימה שהוחלף ב-SigningInfo שלה. למרות ש-SigningInfo בגרסה 4 לא כולל את שושלת הנתונים המלאה של החתימה, הוא יכול לשלוף אותה מבלוק החתימה בגרסה 3 כדי לאפשר לפלטפורמה גישה לשושלת הנתונים לכל שאילתת חתימה. כשמשתמשים בגרסה 3.1 כדי לטרגט רוטציה עבור rotation-min-sdk-version שסופק, ההגדרה הגנרית של גרסה 3 כוללת גם את הגדרת החתימה המקורית וגם את הגדרת החתימה העדכנית שעברה רוטציה. נוצרת הרחבה של סכמת החתימה v4, שכוללת בלוקים נוספים של פרטי חתימה לכל אחת מהגדרות החתימה מהבלוק v3.1.
אימות
כדי לבדוק את ההטמעה של גרסה 3.1, מריצים את PkgInstallSignatureVerificationTest.javaבדיקות CTS ב-cts/hostsidetests/appsecurity/src/android/appsecurity/cts/.
מידע נוסף על בדיקות זמין בקטע אימות בגרסה 3.