डायरेक्ट बूट मोड के साथ काम करना

जब डिवाइस चालू हो, लेकिन उपयोगकर्ता ने डिवाइस को अनलॉक न किया हो, तब Android 7.0, सुरक्षित डायरेक्ट बूट मोड में चलता है. इसके लिए, सिस्टम डेटा को सेव करने की दो जगहें उपलब्ध कराता है:

  • क्रेडेंशियल के लिए एन्क्रिप्ट (सुरक्षित) किया गया स्टोरेज. यह डिफ़ॉल्ट स्टोरेज लोकेशन है और सिर्फ़ तब उपलब्ध होती है, जब उपयोगकर्ता ने डिवाइस को अनलॉक कर लिया हो.
  • डिवाइस का एन्क्रिप्ट (सुरक्षित) किया गया स्टोरेज. यह स्टोरेज की ऐसी जगह होती है जो डायरेक्ट बूट मोड के दौरान और उपयोगकर्ता के डिवाइस अनलॉक करने के बाद, दोनों समय उपलब्ध होती है.

डिफ़ॉल्ट रूप से, डायरेक्ट बूट मोड के दौरान ऐप्लिकेशन नहीं चलते. अगर आपके ऐप्लिकेशन को डायरेक्ट बूट मोड के दौरान कोई कार्रवाई करनी है, तो इस मोड के दौरान चलाने के लिए ऐप्लिकेशन कॉम्पोनेंट रजिस्टर किए जा सकते हैं. डायरेक्ट बूट मोड में चलने वाले ऐप्लिकेशन के कुछ सामान्य इस्तेमाल के उदाहरण यहां दिए गए हैं:

  • ऐसे ऐप्लिकेशन जिनमें सूचनाएँ शेड्यूल की जाती हैं, जैसे कि अलार्म क्लॉक ऐप्लिकेशन.
  • ऐसे ऐप्लिकेशन जो उपयोगकर्ताओं को ज़रूरी सूचनाएं देते हैं. जैसे, एसएमएस ऐप्लिकेशन.
  • ऐसे ऐप्लिकेशन जो सुलभता सेवाएं उपलब्ध कराते हैं, जैसे कि Talkback.

अगर आपके ऐप्लिकेशन को डायरेक्ट बूट मोड में चलते समय डेटा ऐक्सेस करने की ज़रूरत है, तो डिवाइस के एन्क्रिप्ट किए गए स्टोरेज का इस्तेमाल करें. डिवाइस के एन्क्रिप्ट किए गए स्टोरेज में, ऐसी कुंजी से एन्क्रिप्ट किया गया डेटा होता है जो सिर्फ़ तब उपलब्ध होती है, जब डिवाइस ने पुष्टि किया गया बूट पूरा कर लिया हो.

अगर आपको ऐसे डेटा को एन्क्रिप्ट (सुरक्षित) करना है जिसे उपयोगकर्ता के क्रेडेंशियल से जुड़ी किसी कुंजी से एन्क्रिप्ट किया जाना चाहिए, तो क्रेडेंशियल एन्क्रिप्टेड स्टोरेज का इस्तेमाल करें. जैसे, पिन या पासवर्ड. क्रेडेंशियल को एन्क्रिप्ट (सुरक्षित) करके सेव करने की सुविधा, उपयोगकर्ता के डिवाइस को अनलॉक करने के बाद उपलब्ध होती है. यह सुविधा तब तक उपलब्ध रहती है, जब तक उपयोगकर्ता डिवाइस को रीस्टार्ट नहीं करता. अगर उपयोगकर्ता डिवाइस को अनलॉक करने के बाद लॉक स्क्रीन की सुविधा चालू करता है, तो एन्क्रिप्ट किए गए क्रेडेंशियल स्टोरेज की सुविधा उपलब्ध रहती है.

डायरेक्ट बूट के दौरान ऐक्सेस पाने का अनुरोध करें

ऐप्लिकेशन को अपने कॉम्पोनेंट, सिस्टम के साथ रजिस्टर करने होंगे. इसके बाद ही, वे डायरेक्ट बूट मोड में चल पाएंगे या डिवाइस के एन्क्रिप्ट (सुरक्षित) किए गए स्टोरेज को ऐक्सेस कर पाएंगे. ऐप्लिकेशन, कॉम्पोनेंट को encryption aware के तौर पर मार्क करके, सिस्टम के साथ रजिस्टर करते हैं. अपने कॉम्पोनेंट को एन्क्रिप्ट (सुरक्षित) करने की सुविधा के साथ काम करने वाला कॉम्पोनेंट के तौर पर मार्क करने के लिए, अपने मेनिफ़ेस्ट में android:directBootAware एट्रिब्यूट को सही पर सेट करें.

एन्क्रिप्शन की जानकारी रखने वाले कॉम्पोनेंट, डिवाइस के रीस्टार्ट होने पर सिस्टम से 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 इंस्टेंस बनाएं. इस कॉन्टेक्स्ट का इस्तेमाल करके किए गए सभी स्टोरेज एपीआई कॉल, डिवाइस के एन्क्रिप्ट (सुरक्षित) किए गए स्टोरेज को ऐक्सेस करते हैं. यहां दिए गए उदाहरण में, डिवाइस के एन्क्रिप्ट (सुरक्षित) किए गए स्टोरेज को ऐक्सेस किया गया है. साथ ही, ऐप्लिकेशन के मौजूदा डेटा की फ़ाइल खोली गई है:

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() पर कॉल करके इसकी जानकारी पाई जा सकती है.

मौजूदा डेटा माइग्रेट करना

अगर कोई उपयोगकर्ता, डायरेक्ट बूट मोड का इस्तेमाल करने के लिए अपने डिवाइस को अपडेट करता है, तो आपके पास ऐसा मौजूदा डेटा हो सकता है जिसे डिवाइस के एन्क्रिप्ट (सुरक्षित) किए गए स्टोरेज में माइग्रेट करने की ज़रूरत हो. क्रेडेंशियल एन्क्रिप्ट (सुरक्षित) किए गए स्टोरेज और डिवाइस एन्क्रिप्ट (सुरक्षित) किए गए स्टोरेज के बीच, प्राथमिकताओं और डेटाबेस के डेटा को माइग्रेट करने के लिए, Context.moveSharedPreferencesFrom() और Context.moveDatabaseFrom() का इस्तेमाल करें. इसमें डेस्टिनेशन कॉन्टेक्स्ट को मेथड कॉलर और सोर्स कॉन्टेक्स्ट को आर्ग्युमेंट के तौर पर इस्तेमाल किया जाता है.

उपयोगकर्ता की निजी जानकारी को क्रेडेंशियल के एन्क्रिप्ट (सुरक्षित) किए गए स्टोरेज से डिवाइस के एन्क्रिप्ट (सुरक्षित) किए गए स्टोरेज में माइग्रेट न करें. जैसे, पासवर्ड या अनुमति देने वाले टोकन. डिवाइस के एन्क्रिप्ट किए गए स्टोरेज में कौनसा डेटा माइग्रेट करना है, यह तय करने के लिए अपनी सूझ-बूझ का इस्तेमाल करें. कुछ मामलों में, आपको दोनों एन्क्रिप्ट (सुरक्षित) किए गए स्टोर में डेटा के अलग-अलग सेट मैनेज करने पड़ सकते हैं.

एन्क्रिप्शन की सुविधा वाले ऐप्लिकेशन की जांच करना

डायरेक्ट बूट मोड चालू करके, एन्क्रिप्शन की जानकारी रखने वाले ऐप्लिकेशन की जांच करें.

Android के नए वर्शन वाले ज़्यादातर डिवाइसों में, लॉकस्क्रीन क्रेडेंशियल (पिन, पैटर्न या पासवर्ड) सेट करने पर डायरेक्ट बूट मोड चालू हो जाता है. खास तौर पर, ऐसा उन सभी डिवाइसों पर होता है जिनमें फ़ाइल आधारित एन्क्रिप्शन का इस्तेमाल किया जाता है. यह देखने के लिए कि कोई डिवाइस, फ़ाइल-आधारित एन्क्रिप्शन का इस्तेमाल करता है या नहीं, यहां दिया गया शेल कमांड चलाएं:

adb shell getprop ro.crypto.type

अगर आउटपुट file है, तो इसका मतलब है कि डिवाइस पर अलग-अलग फ़ाइलों को अलग-अलग तरीकों से एन्क्रिप्ट करने का तरीका चालू है.

जिन डिवाइसों पर डिफ़ॉल्ट रूप से, अलग-अलग फ़ाइलों को अलग-अलग तरीकों से एन्क्रिप्ट करने का तरीका इस्तेमाल नहीं किया जाता है उन पर डायरेक्ट बूट मोड की जांच करने के लिए, ये विकल्प उपलब्ध हो सकते हैं:

  • जिन डिवाइसों में फ़ुल-डिस्क एन्क्रिप्शन (ro.crypto.type=block) का इस्तेमाल किया जाता है और जिनमें Android 7.0 से लेकर Android 12 तक का वर्शन है उन्हें फ़ाइल-आधारित एन्क्रिप्शन में बदला जा सकता है. ऐसा करने के दो तरीके हैं:

      चेतावनी: फ़ाइल के आधार पर सुरक्षित करने के तरीके में बदलने के लिए, दोनों में से किसी भी तरीके का इस्तेमाल करने पर, डिवाइस पर मौजूद उपयोगकर्ता का सारा डेटा मिट जाता है.

    • अगर आपने पहले से डेवलपर के लिए सेटिंग और टूल चालू नहीं किए हैं, तो डिवाइस पर इन्हें चालू करें. इसके लिए, सेटिंग > फ़ोन के बारे में जानकारी पर जाएं और बिल्ड नंबर पर सात बार टैप करें. इसके बाद, सेटिंग > डेवलपर के लिए सेटिंग और टूल पर जाएं और फ़ाइल एन्क्रिप्शन में बदलें को चुनें.
    • इसके अलावा, यहां दिए गए शेल कमांड भी चलाए जा सकते हैं:
      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() का इस्तेमाल कर सकते हैं.

अगर आपका ऐप्लिकेशन, Android 7.0 (एपीआई 24) से कम एपीआई लेवल को टारगेट करता है, तो getStorageEncryptionStatus() यह वैल्यू दिखाता है: ENCRYPTION_STATUS_ACTIVE अगर डिवाइस में फ़ुल-डिस्क एन्क्रिप्शन या डायरेक्ट बूट के साथ फ़ाइल-आधारित एन्क्रिप्शन का इस्तेमाल किया जा रहा है. इन दोनों ही मामलों में, डेटा को हमेशा एन्क्रिप्ट (सुरक्षित) करके सेव किया जाता है.

अगर आपका ऐप्लिकेशन Android 7.0 (एपीआई 24) या इसके बाद के वर्शन को टारगेट करता है, तो getStorageEncryptionStatus() यह वैल्यू तब दिखती है, जब डिवाइस में फ़ुल-डिस्क एन्क्रिप्शन का इस्तेमाल किया जा रहा हो.ENCRYPTION_STATUS_ACTIVE अगर डिवाइस पर डायरेक्ट बूट के साथ फ़ाइल-आधारित एन्क्रिप्शन का इस्तेमाल किया जा रहा है, तो यह ENCRYPTION_STATUS_ACTIVE_PER_USER दिखाता है.

अगर आपको Android 7.0 के लिए डिवाइस एडमिनिस्ट्रेशन ऐप्लिकेशन बनाना है, तो पक्का करें कि डिवाइस एन्क्रिप्ट (सुरक्षित) है या नहीं, यह पता लगाने के लिए ENCRYPTION_STATUS_ACTIVE और ENCRYPTION_STATUS_ACTIVE_PER_USER, दोनों की जांच की गई हो.

अन्य कोड सैंपल

DirectBoot सैंपल में, इस पेज पर बताए गए एपीआई के इस्तेमाल के बारे में ज़्यादा जानकारी दी गई है.