תמיכה במצב הפעלה ישירה

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

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

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

  • אפליקציות עם התראות מתוזמנות, כמו אפליקציות של שעון מעורר.
  • אפליקציות שמספקות התראות חשובות למשתמשים, כמו אפליקציות SMS.
  • אפליקציות שמספקות שירותי נגישות, כמו TalkBack.

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

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

שליחת בקשה לקבלת גישה להפעלה במהלך הפעלה ישירה (Direct Boot)

האפליקציות צריכות לרשום את הרכיבים שלהן במערכת כדי שיוכלו לפעול במצב Direct Boot או לגשת לאחסון המוצפן של המכשיר. אפליקציות נרשמות במערכת על ידי סימון רכיבים כמודעים להצפנה. כדי לסמן את הרכיב כרכיב שמודע להצפנה, מגדירים את המאפיין android:directBootAware כ-true במניפסט.

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

קטע הקוד הבא הוא דוגמה לאופן שבו רושמים את BroadcastReceiver כקובץ עם תמיכה בהצפנה, ומוסיפים מסנן Intent עבור ACTION_LOCKED_BOOT_COMPLETED במניפסט של האפליקציה:

<receiver
  android:directBootAware="true" >
  ...
  <intent-filter>
    <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
  </intent-filter>
</receiver>

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

גישה לאחסון המוצפן במכשיר

כדי לגשת לאחסון מוצפן במכשיר, יוצרים מכונה שנייה של Context באמצעות קריאה ל-Context.createDeviceProtectedStorageContext(). כל הקריאות ל-Storage API שמבוצעות באמצעות ההקשר הזה מאפשרות גישה לאחסון המוצפן של המכשיר. בדוגמה הבאה מתבצעת גישה לאחסון המוצפן של המכשיר ופתיחת קובץ קיים של נתוני אפליקציה:

Kotlin

val directBootContext: Context = appContext.createDeviceProtectedStorageContext()
// Access appDataFilename that lives in device encrypted storage
val inStream: InputStream = directBootContext.openFileInput(appDataFilename)
// Use inStream to read content...

Java

Context directBootContext = appContext.createDeviceProtectedStorageContext();
// Access appDataFilename that lives in device encrypted storage
FileInputStream inStream = directBootContext.openFileInput(appDataFilename);
// Use inStream to read content...

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

קבלת התראות על פתיחה של מנעול על ידי משתמש

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

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

  • אם לאפליקציה יש תהליכים בחזית שצריכים התראה מיידית, צריך להאזין להודעה ACTION_USER_UNLOCKED.
  • אם האפליקציה שלכם משתמשת רק בתהליכי רקע שיכולים להגיב להודעה מושהית, צריך להאזין להודעה ACTION_BOOT_COMPLETED.

כדי לבדוק אם המשתמש ביטל את נעילת המכשיר, אפשר להתקשר למספר UserManager.isUserUnlocked().

העברת נתונים קיימים

אם משתמש מעדכן את המכשיר שלו כך שישתמש במצב Direct Boot, יכול להיות שיהיו לכם נתונים קיימים שצריך להעביר לאחסון המוצפן של המכשיר. כדי להעביר העדפות ונתוני מסדי נתונים בין אחסון מוצפן של פרטי כניסה לאחסון מוצפן במכשיר, משתמשים ב-Context.moveSharedPreferencesFrom() וב-Context.moveDatabaseFrom(), כאשר הקשר של היעד הוא מבצע הקריאה ל-method והקשר של המקור הוא הארגומנט.

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

בדיקת האפליקציה עם תמיכה בהצפנה

בודקים את האפליקציה עם התמיכה בהצפנה כשמצב Direct Boot מופעל.

ברוב המכשירים עם גרסאות עדכניות של Android מופעל מצב הפעלה ישירה (Direct Boot) בכל פעם שמוגדר פרטי כניסה למסך הנעילה (קוד אימות, קו ביטול נעילה או סיסמה). באופן ספציפי, המצב הזה קיים בכל המכשירים שמשתמשים בהצפנה מבוססת-קבצים. כדי לבדוק אם במכשיר נעשה שימוש בהצפנה מבוססת-קובץ, מריצים את הפקודה הבאה במסוף:

adb shell getprop ro.crypto.type

אם הפלט הוא file, המשמעות היא שההצפנה מבוססת-הקבצים מופעלת במכשיר.

במכשירים שלא משתמשים בהצפנה מבוססת-קובץ כברירת מחדל, יכול להיות שיהיו אפשרויות אחרות לבדיקה של מצב Direct Boot:

  • אפשר להמיר מכשירי Android מסוימים עם הצפנה מלאה של הדיסק (ro.crypto.type=block) בגרסאות Android 7.0 עד Android 12 להצפנה מבוססת-קובץ. ניתן לעשות זאת בשתי דרכים:

      אזהרה: כל אחת מהשיטות להמרה להצפנה מבוססת-קבצים מוחקת את כל נתוני המשתמשים במכשיר.

    • במכשיר, מפעילים את האפשרויות למפתחים, אם עדיין לא עשיתם זאת, על ידי מעבר אל הגדרות > מידע על הטלפון והקשה על מספר Build שבע פעמים. לאחר מכן עוברים אל הגדרות > אפשרויות למפתחים ובוחרים באפשרות המרה להצפנת קובץ.
    • לחלופין, מריצים את פקודות המעטפת הבאות:
      adb reboot-bootloader
      fastboot --wipe-and-use-fbe
      
  • במכשירים עם Android מגרסה 13 ומטה יש תמיכה במצב 'הפעלה ישירה' 'הדמוי', שמשתמש בהרשאות קבצים כדי לדמות את ההשפעות של נעילה וביטול נעילה של קבצים מוצפנים. משתמשים במצב הדמיה רק במהלך הפיתוח, כי הוא עלול לגרום לאובדן נתונים. כדי להפעיל את המצב המאומלץ של Direct Boot, מגדירים דפוס נעילה במכשיר, בוחרים באפשרות 'לא תודה' אם מופיעה בקשה להגדרת מסך הפעלה מאובטח כשמגדירים את דפוס הנעילה, ואז מריצים את פקודת המעטפת הבאה:

    adb shell sm set-emulate-fbe true
    

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

    adb shell sm set-emulate-fbe false
    

    הפעלת אחת מהפקודות האלה תגרום להפעלה מחדש של המכשיר.

בדיקת סטטוס ההצפנה של מדיניות המכשיר

אפליקציות לניהול המכשיר יכולות להשתמש ב-DevicePolicyManager.getStorageEncryptionStatus() כדי לבדוק את סטטוס ההצפנה הנוכחי של המכשיר.

אם האפליקציה מטרגטת רמת API נמוכה יותר מ-Android 7.0‏ (API 24), הפונקציה getStorageEncryptionStatus() מחזירה את הערך ENCRYPTION_STATUS_ACTIVE אם במכשיר מופעלת הצפנה מלאה של הדיסק או הצפנה מבוססת-קובץ עם Direct Boot. בשני המקרים האלה, הנתונים תמיד מאוחסנים מוצפנים במנוחה.

אם האפליקציה שלכם מטרגטת את Android 7.0 (API 24) ואילך, הפונקציה getStorageEncryptionStatus() מחזירה את הערך ENCRYPTION_STATUS_ACTIVE אם במכשיר מופעלת הצפנה מלאה של הדיסק. הפונקציה מחזירה את הערך ENCRYPTION_STATUS_ACTIVE_PER_USER אם המכשיר משתמש בהצפנה מבוססת-קבצים עם הפעלה ישירה.

אם אתם מפתחים אפליקציה לניהול מכשירים שמטרגטת את Android 7.0, חשוב לבדוק גם את ENCRYPTION_STATUS_ACTIVE וגם את ENCRYPTION_STATUS_ACTIVE_PER_USER כדי לקבוע אם המכשיר מוצפן.

דוגמאות קוד נוספות

הדוגמה DirectBoot ממחישה את השימוש בממשקי ה-API שמפורטים בדף הזה.