پشتیبانی از حالت Direct Boot

زمانی که دستگاه روشن شده باشد اما کاربر قفل دستگاه را باز نکرده باشد، اندروید 7.0 در حالت راه‌اندازی مستقیم و ایمن اجرا می‌شود. برای پشتیبانی از این، سیستم دو مکان ذخیره سازی برای داده ها فراهم می کند:

  • فضای ذخیره‌سازی رمزگذاری‌شده اعتبار ، که مکان ذخیره‌سازی پیش‌فرض است و تنها پس از باز کردن قفل دستگاه توسط کاربر در دسترس است.
  • ذخیره‌سازی رمزگذاری‌شده دستگاه ، که یک مکان ذخیره‌سازی است که هم در حالت راه‌اندازی مستقیم و هم پس از باز کردن قفل دستگاه توسط کاربر در دسترس است.

به‌طور پیش‌فرض، برنامه‌ها در حالت Direct Boot اجرا نمی‌شوند. اگر برنامه شما نیاز به اقدامی در هنگام راه‌اندازی مستقیم دارد، می‌توانید اجزای برنامه را برای اجرا در این حالت ثبت کنید. برخی از موارد استفاده رایج برای برنامه‌هایی که نیاز به اجرا در حالت راه‌اندازی مستقیم دارند عبارتند از:

  • برنامه هایی که اعلان های برنامه ریزی شده دارند، مانند برنامه های ساعت زنگ دار.
  • برنامه‌هایی که اعلان‌های مهم کاربر را ارائه می‌کنند، مانند برنامه‌های پیام کوتاه.
  • برنامه‌هایی که خدمات دسترس‌پذیری را ارائه می‌کنند، مانند Talkback.

اگر برنامه شما نیاز به دسترسی به داده ها در هنگام اجرا در حالت راه اندازی مستقیم دارد، از حافظه رمزگذاری شده دستگاه استفاده کنید. فضای ذخیره‌سازی رمزگذاری‌شده دستگاه حاوی داده‌های رمزگذاری‌شده با یک کلید است که تنها پس از راه‌اندازی تأییدشده توسط دستگاه در دسترس است.

برای داده‌هایی که باید با یک کلید مرتبط با اطلاعات کاربری کاربر، مانند پین یا رمز عبور رمزگذاری شوند، از فضای ذخیره‌سازی رمزگذاری شده اعتبار استفاده کنید. پس از اینکه کاربر با موفقیت قفل دستگاه را باز کرد و تا زمانی که کاربر دستگاه را راه اندازی مجدد کند، فضای ذخیره رمزگذاری شده اعتبارنامه در دسترس است. اگر کاربر پس از باز کردن قفل دستگاه، صفحه قفل را فعال کند، فضای ذخیره‌سازی رمزگذاری شده اعتبارنامه در دسترس باقی می‌ماند.

درخواست دسترسی برای اجرا در هنگام راه‌اندازی مستقیم

برنامه‌ها قبل از اینکه بتوانند در حالت راه‌اندازی مستقیم اجرا شوند یا به فضای ذخیره‌سازی رمزگذاری‌شده دستگاه دسترسی پیدا کنند، باید اجزای خود را در سیستم ثبت کنند. برنامه ها با علامت گذاری مؤلفه ها به عنوان آگاه از رمزگذاری در سیستم ثبت می شوند. برای علامت گذاری مؤلفه خود به عنوان آگاه از رمزگذاری، ویژگی android:directBootAware در مانیفست خود روی true تنظیم کنید.

مؤلفه‌های آگاه از رمزگذاری می‌توانند برای دریافت پیام پخش ACTION_LOCKED_BOOT_COMPLETED از سیستم پس از راه‌اندازی مجدد دستگاه ثبت نام کنند. در این مرحله فضای ذخیره‌سازی رمزگذاری‌شده دستگاه در دسترس است و مؤلفه شما می‌تواند وظایفی را که باید در حالت راه‌اندازی مستقیم اجرا شوند، مانند راه‌اندازی زنگ برنامه‌ریزی‌شده، اجرا کند.

قطعه کد زیر نمونه ای از نحوه ثبت یک BroadcastReceiver به عنوان آگاه از رمزگذاری، و افزودن فیلتر قصد برای ACTION_LOCKED_BOOT_COMPLETED در مانیفست برنامه است:

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

هنگامی که کاربر قفل دستگاه را باز کرد، همه اجزا می توانند به حافظه رمزگذاری شده دستگاه و همچنین حافظه رمزگذاری شده اعتبار دسترسی داشته باشند.

به حافظه رمزگذاری شده دستگاه دسترسی پیدا کنید

برای دسترسی به حافظه رمزگذاری شده دستگاه، با فراخوانی Context.createDeviceProtectedStorageContext() یک نمونه Context دوم ایجاد کنید. همه تماس‌های API ذخیره‌سازی که با استفاده از این زمینه انجام می‌شوند به فضای ذخیره‌سازی رمزگذاری‌شده دستگاه دسترسی دارند. مثال زیر به حافظه رمزگذاری شده دستگاه دسترسی پیدا می کند و یک فایل داده برنامه موجود را باز می کند:

کاتلین

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

جاوا

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() متوجه شوید.

انتقال داده های موجود

اگر کاربر دستگاه خود را برای استفاده از حالت راه‌اندازی مستقیم به‌روزرسانی کند، ممکن است داده‌های موجودی داشته باشید که باید به فضای ذخیره‌سازی رمزگذاری شده دستگاه منتقل شوند. از Context.moveSharedPreferencesFrom() و Context.moveDatabaseFrom() با متن مقصد به عنوان فراخوان متد و زمینه منبع به عنوان آرگومان، برای انتقال اولویت و داده های پایگاه داده بین حافظه رمزگذاری شده اعتبار و حافظه رمزگذاری شده دستگاه استفاده کنید.

اطلاعات خصوصی کاربر، مانند گذرواژه‌ها یا نشانه‌های مجوز، را از فضای ذخیره‌سازی رمزگذاری‌شده اعتبارنامه به فضای ذخیره‌سازی رمزگذاری‌شده دستگاه منتقل نکنید. هنگام تصمیم گیری برای انتقال داده های دیگر به حافظه رمزگذاری شده دستگاه، بهترین قضاوت خود را به کار ببرید. در برخی سناریوها، ممکن است لازم باشد مجموعه های جداگانه ای از داده ها را در دو فروشگاه رمزگذاری شده مدیریت کنید.

برنامه آگاه از رمزگذاری خود را آزمایش کنید

برنامه آگاه از رمزگذاری خود را با فعال کردن حالت مستقیم بوت آزمایش کنید.

اکثر دستگاه‌هایی که نسخه‌های اخیر اندروید را اجرا می‌کنند، هر زمان که یک اعتبار صفحه قفل (پین، الگو یا رمز عبور) تنظیم شده باشد، حالت راه‌اندازی مستقیم را فعال می‌کنند. به طور خاص، این مورد در همه دستگاه‌هایی است که از رمزگذاری مبتنی بر فایل استفاده می‌کنند. برای بررسی اینکه آیا یک دستگاه از رمزگذاری مبتنی بر فایل استفاده می کند یا خیر، دستور پوسته زیر را اجرا کنید:

adb shell getprop ro.crypto.type

اگر خروجی file باشد، پس دستگاه رمزگذاری مبتنی بر فایل را فعال کرده است.

در دستگاه‌هایی که به‌طور پیش‌فرض از رمزگذاری مبتنی بر فایل استفاده نمی‌کنند، ممکن است گزینه‌های دیگری برای آزمایش حالت راه‌اندازی مستقیم وجود داشته باشد:

  • برخی از دستگاه‌هایی که از رمزگذاری فول دیسک ( ro.crypto.type=block ) استفاده می‌کنند و از Android 7.0 تا Android 12 استفاده می‌کنند، می‌توانند به رمزگذاری مبتنی بر فایل تبدیل شوند. دو راه برای این کار وجود دارد:

      هشدار: هر یک از روش‌های تبدیل به رمزگذاری مبتنی بر فایل، تمام داده‌های کاربر روی دستگاه را پاک می‌کند.

    • اگر قبلاً این کار را نکرده اید، در دستگاه، گزینه های برنامه نویس را با رفتن به تنظیمات > درباره تلفن و هفت بار ضربه زدن روی Build number فعال کنید. سپس به Settings > Developer options رفته و Convert to file encryption را انتخاب کنید.
    • همچنین، دستورات پوسته زیر را اجرا کنید:
      adb reboot-bootloader
      fastboot --wipe-and-use-fbe
      
  • دستگاه‌هایی که Android 13 یا پایین‌تر دارند، از یک حالت راه‌اندازی مستقیم «شبیه‌شده» پشتیبانی می‌کنند که از مجوزهای فایل برای شبیه‌سازی اثرات قفل و باز شدن قفل فایل‌های رمزگذاری‌شده استفاده می‌کند. فقط از حالت شبیه سازی شده در طول توسعه استفاده کنید. می تواند باعث از دست رفتن اطلاعات شود. برای فعال کردن حالت راه‌اندازی مستقیم شبیه‌سازی‌شده، یک الگوی قفل را روی دستگاه تنظیم کنید، اگر هنگام تنظیم الگوی قفل از صفحه راه‌اندازی ایمن خواسته شد، «نه متشکرم» را انتخاب کنید و سپس دستور پوسته زیر را اجرا کنید:

    adb shell sm set-emulate-fbe true
    

    برای خاموش کردن حالت مستقیم بوت شبیه سازی شده، دستور پوسته زیر را اجرا کنید:

    adb shell sm set-emulate-fbe false
    

    اجرای هر یک از این دستورات باعث راه اندازی مجدد دستگاه می شود.

وضعیت رمزگذاری خط مشی دستگاه را بررسی کنید

برنامه‌های مدیریت دستگاه می‌توانند از DevicePolicyManager.getStorageEncryptionStatus() برای بررسی وضعیت رمزگذاری فعلی دستگاه استفاده کنند.

اگر برنامه شما سطح API کمتر از Android 7.0 (API 24) را هدف قرار دهد، اگر دستگاه از رمزگذاری تمام دیسک یا رمزگذاری مبتنی بر فایل با Direct Boot استفاده می‌کند 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های پوشش داده شده در این صفحه را نشان می دهد.