מערכת Android 7.0 פועלת במצב מאובטח של הפעלה ישירה כשהמכשיר מופעל אבל המשתמש לא פותח את נעילת המכשיר. כדי לתמוך בכך, המערכת מספקת שני מיקומי אחסון של נתונים:
- אחסון מוצפן של פרטי כניסה – מיקום האחסון שמוגדר כברירת מחדל, והוא זמין רק אחרי שהמשתמש ביטל את נעילת המכשיר.
- אחסון מוצפן במכשיר, שהוא מיקום אחסון שזמין גם במצב Direct Boot וגם אחרי שהמשתמש מבטל את נעילת המכשיר.
כברירת מחדל, אפליקציות לא פועלות במצב Direct Boot. אם האפליקציה שלכם צריכה לבצע פעולה במהלך מצב Direct Boot, תוכלו לרשום רכיבי אפליקציה להפעלה במהלך המצב הזה. דוגמאות לתרחישים נפוצים של אפליקציות שצריכות לפעול במצב Direct Boot:
- אפליקציות עם התראות מתוזמנות, כמו אפליקציות של שעון מעורר.
- אפליקציות שמספקות התראות חשובות למשתמשים, כמו אפליקציות SMS.
- אפליקציות שמספקות שירותי נגישות, כמו TalkBack.
אם האפליקציה צריכה לגשת לנתונים בזמן שהיא פועלת במצב Direct Boot, צריך להשתמש באחסון מוצפן במכשיר. האחסון המוצפן של המכשיר מכיל נתונים שמוצפנים באמצעות מפתח, שזמין רק אחרי שהמכשיר ביצע הפעלה מאומתת בהצלחה.
לנתונים שצריך להצפין באמצעות מפתח שמשויך לפרטי הכניסה של המשתמש, כמו קוד אימות או סיסמה, צריך להשתמש באחסון מוצפן של פרטי הכניסה. האחסון המוצפן של פרטי הכניסה זמין אחרי שהמשתמש פותח את נעילת המכשיר, ועד שהוא מפעיל מחדש את המכשיר. אם המשתמש מפעיל את מסך הנעילה אחרי ביטול הנעילה של המכשיר, האחסון המוצפן של פרטי הכניסה יישאר זמין.
שליחת בקשה לקבלת גישה להפעלה במהלך הפעלה ישירה (Direct Boot)
כדי שאפליקציות יוכלו לרוץ במצב הפעלה ישירה או לגשת לאחסון המוצפן במכשיר, המפתחים צריכים לרשום את הרכיבים שלהן במערכת. אפליקציות נרשמות במערכת על ידי סימון רכיבים כמודעים להצפנה. כדי לסמן את הרכיב כרכיב שמודע להצפנה, מגדירים את המאפיין android:directBootAware
כ-true במניפסט.
רכיבים מודעים להצפנה יכולים להירשם לקבלת הודעת שידור ACTION_LOCKED_BOOT_COMPLETED
מהמערכת אחרי שהמכשיר הופעל מחדש. בשלב הזה, האחסון המוצפן של המכשיר זמין והרכיב יכול לבצע משימות שצריך להריץ במצב Direct Boot, כמו הפעלת אזעקה מתוזמנת.
קטע הקוד הבא הוא דוגמה לרישום של BroadcastReceiver
כמוּדעוּת להצפנה, ולהוספה של מסנן כוונה עבור 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...
יש להשתמש באחסון מוצפן במכשיר רק למידע שצריך להיות נגיש במהלך מצב ההפעלה הישירה. אין להשתמש באחסון המוצפן במכשיר כמאגר מוצפן למטרות כלליות. כדי לקבל מידע פרטי של משתמשים או נתונים מוצפנים שלא נחוצים במצב הפעלה ישירה, צריך להשתמש באחסון מוצפן של פרטי כניסה.
קבלת התראות על פתיחה של מנעול על ידי משתמש
כשהמשתמש פותח את המכשיר אחרי ההפעלה מחדש, האפליקציה יכולה לעבור לגישה לאחסון המוצפן של פרטי הכניסה ולהשתמש בשירותי מערכת רגילים שמסתמכים על פרטי הכניסה של המשתמש.
כדי לקבל התראה כשהמשתמש פותח את המכשיר אחרי הפעלה מחדש, צריך לרשום BroadcastReceiver
מרכיב שפועל כדי להאזין להודעות של התראות על ביטול נעילה. כשהמשתמש מבטל את נעילת המכשיר אחרי האתחול:
- אם באפליקציה יש תהליכים בחזית שדורשים התראה מיידית,
כדאי להאזין להודעה
ACTION_USER_UNLOCKED
. - אם האפליקציה משתמשת רק בתהליכים ברקע שיכולים לטפל בהתראה מאוחרת, כדאי להאזין להודעה
ACTION_BOOT_COMPLETED
.
כדי לבדוק אם המשתמש ביטל את נעילת המכשיר, אפשר להתקשר למספר UserManager.isUserUnlocked()
.
העברת נתונים קיימים
אם משתמש מעדכן את המכשיר שלו כך שישתמש במצב Direct Boot, יכול להיות שיהיו לכם נתונים קיימים שצריך להעביר לאחסון המוצפן של המכשיר. משתמשים ב-Context.moveSharedPreferencesFrom()
וב-Context.moveDatabaseFrom()
, כשההקשר של היעד הוא רכיב הקריאה של השיטה והקשר המקור כארגומנט, כדי להעביר את ההעדפות ואת נתוני מסד הנתונים בין האחסון המוצפן של פרטי הכניסה לאחסון המוצפן במכשיר.
אין להעביר פרטי משתמשים פרטיים, כמו סיסמאות או אסימוני הרשאה, מאחסון מוצפן של פרטי כניסה לאחסון מוצפן במכשיר. מומלץ להפעיל שיקול דעת כשמחליטים אילו נתונים נוספים להעביר לאחסון המוצפן במכשיר. במקרים מסוימים, יכול להיות שתצטרכו לנהל קבוצות נפרדות של נתונים בשני המאגרים המוצפנים.
בדיקת האפליקציה עם תמיכה בהצפנה
בודקים את האפליקציה עם התמיכה בהצפנה כשמצב Direct Boot מופעל.
רוב המכשירים שבהם פועלת הגרסאות האחרונות של Android מפעילים את מצב הפעלה ישירה בכל פעם שהוגדרו פרטי כניסה למסך הנעילה (קוד אימות, קו ביטול נעילה או סיסמה). באופן ספציפי, המצב הזה קיים בכל המכשירים שמשתמשים בהצפנה מבוססת-קבצים. כדי לבדוק אם במכשיר יש הצפנה מבוססת-קבצים, מריצים את פקודת המעטפת הבאה:
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
אם המכשיר משתמש בהצפנת דיסק מלא או בהצפנה מבוססת-קבצים עם הפעלה ישירה. בשני המקרים האלה, הנתונים תמיד מאוחסנים מוצפנים במנוחה.
אם האפליקציה שלכם מטרגטת את 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 שמפורטים בדף הזה.