ডিভাইসটি চালু থাকা অবস্থায় কিন্তু ব্যবহারকারী ডিভাইসটি আনলক না করলে, অ্যান্ড্রয়েড ৭.০ একটি সুরক্ষিত, ডাইরেক্ট বুট মোডে চলে। এটিকে সমর্থন করার জন্য, সিস্টেম ডেটার জন্য দুটি স্টোরেজ লোকেশন প্রদান করে:
- ক্রেডেনশিয়াল এনক্রিপ্টেড স্টোরেজ , যা হলো ডিফল্ট স্টোরেজ লোকেশন এবং ব্যবহারকারী ডিভাইসটি আনলক করার পরেই কেবল এটি উপলব্ধ হয়।
- ডিভাইস এনক্রিপ্টেড স্টোরেজ , যা এমন একটি স্টোরেজ লোকেশন যা ডাইরেক্ট বুট মোডে এবং ব্যবহারকারী ডিভাইসটি আনলক করার পরেও উপলব্ধ থাকে।
ডিফল্টরূপে, অ্যাপগুলো ডিরেক্ট বুট মোডে চলে না। যদি আপনার অ্যাপের ডিরেক্ট বুট মোডে কোনো কাজ করার প্রয়োজন হয়, তবে আপনি এই মোডে চালানোর জন্য অ্যাপের উপাদানগুলো রেজিস্টার করতে পারেন। ডিরেক্ট বুট মোডে অ্যাপ চলার কিছু সাধারণ ব্যবহারের ক্ষেত্র হলো:
- যেসব অ্যাপে নোটিফিকেশন সেট করার সময় নির্ধারণ করা থাকে, যেমন অ্যালার্ম ক্লক অ্যাপ।
- যেসব অ্যাপ ব্যবহারকারীকে গুরুত্বপূর্ণ নোটিফিকেশন দেয়, যেমন এসএমএস অ্যাপ।
- টকব্যাকের মতো অ্যাপ, যা অ্যাক্সেসিবিলিটি পরিষেবা প্রদান করে।
ডিরেক্ট বুট মোডে চলার সময় আপনার অ্যাপের যদি ডেটা অ্যাক্সেস করার প্রয়োজন হয়, তাহলে ডিভাইস এনক্রিপ্টেড স্টোরেজ ব্যবহার করুন। ডিভাইস এনক্রিপ্টেড স্টোরেজে এমন একটি কী (key) দিয়ে এনক্রিপ্ট করা ডেটা থাকে, যা ডিভাইসটি সফলভাবে ভেরিফায়েড বুট সম্পন্ন করার পরেই কেবল উপলব্ধ হয়।
যেসব ডেটা ব্যবহারকারীর পরিচয়পত্রের (যেমন পিন বা পাসওয়ার্ড) সাথে যুক্ত কোনো কী দিয়ে এনক্রিপ্ট করতে হয়, সেগুলোর জন্য ক্রেডেনশিয়াল এনক্রিপ্টেড স্টোরেজ ব্যবহার করুন। ব্যবহারকারী সফলভাবে ডিভাইসটি আনলক করার পর থেকে ডিভাইসটি রিস্টার্ট না করা পর্যন্ত ক্রেডেনশিয়াল এনক্রিপ্টেড স্টোরেজ উপলব্ধ থাকে। ডিভাইসটি আনলক করার পর যদি ব্যবহারকারী লক স্ক্রিন চালু করেন, তাহলেও ক্রেডেনশিয়াল এনক্রিপ্টেড স্টোরেজ উপলব্ধ থাকে।
ডাইরেক্ট বুট চলাকালীন চালানোর জন্য অ্যাক্সেসের অনুরোধ করুন
ডিরেক্ট বুট মোডে চলার আগে বা ডিভাইসের এনক্রিপ্টেড স্টোরেজ অ্যাক্সেস করার আগে অ্যাপগুলিকে অবশ্যই তাদের কম্পোনেন্টগুলি সিস্টেমের সাথে রেজিস্টার করতে হবে। অ্যাপগুলি কম্পোনেন্টগুলিকে ‘এনক্রিপশন অ্যাওয়্যার’ হিসেবে চিহ্নিত করার মাধ্যমে সিস্টেমের সাথে রেজিস্টার করে। আপনার কম্পোনেন্টকে এনক্রিপশন অ্যাওয়্যার হিসেবে চিহ্নিত করতে, আপনার ম্যানিফেস্টে 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 ইনস্ট্যান্স তৈরি করুন। এই 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) ব্যবহার করে এবং অ্যান্ড্রয়েড ৭.০ থেকে অ্যান্ড্রয়েড ১২ পর্যন্ত চলে, সেগুলোকে ফাইল-ভিত্তিক এনক্রিপশনে রূপান্তর করা যেতে পারে। এটি করার দুটি উপায় আছে:- ডিভাইসে, যদি আগে থেকে চালু করা না থাকে, তাহলে সেটিংস > ফোন সম্পর্কে- তে গিয়ে বিল্ড নম্বরে সাতবার ট্যাপ করে ডেভেলপার অপশন চালু করুন। এরপর সেটিংস > ডেভেলপার অপশন- এ গিয়ে ‘ফাইল এনক্রিপশনে রূপান্তর করুন’ নির্বাচন করুন।
- বিকল্পভাবে, নিম্নলিখিত শেল কমান্ডগুলো চালান:
adb reboot-bootloaderfastboot --wipe-and-use-fbe
সতর্কীকরণ: ফাইল-ভিত্তিক এনক্রিপশনে রূপান্তরের যেকোনো পদ্ধতিই ডিভাইস থেকে ব্যবহারকারীর সমস্ত ডেটা মুছে ফেলবে।
অ্যান্ড্রয়েড ১৩ বা তার নিচের সংস্করণে চালিত ডিভাইসগুলো একটি "এমুলেটেড" ডাইরেক্ট বুট মোড সমর্থন করে, যা ফাইল পারমিশন ব্যবহার করে এনক্রিপ্টেড ফাইল লক এবং আনলক করার প্রভাব অনুকরণ করে। শুধুমাত্র ডেভেলপমেন্টের সময় এমুলেটেড মোড ব্যবহার করুন; এটি ডেটা হারানোর কারণ হতে পারে। এমুলেটেড ডাইরেক্ট বুট মোড চালু করতে, ডিভাইসে একটি লক প্যাটার্ন সেট করুন, লক প্যাটার্ন সেট করার সময় যদি কোনো সিকিওর স্টার্ট-আপ স্ক্রিন দেখানো হয়, তবে "না ধন্যবাদ" (No thanks) নির্বাচন করুন, এবং তারপর নিম্নলিখিত শেল কমান্ডটি চালান:
adb shell sm set-emulate-fbe true
এমুলেটেড ডিরেক্ট বুট মোড বন্ধ করতে, নিম্নলিখিত শেল কমান্ডটি চালান:
adb shell sm set-emulate-fbe false
এই কমান্ডগুলোর যেকোনো একটি চালালে ডিভাইসটি রিবুট হয়।
ডিভাইস পলিসি এনক্রিপশন স্ট্যাটাস চেক করুন
ডিভাইস অ্যাডমিনিস্ট্রেশন অ্যাপগুলো ডিভাইসের বর্তমান এনক্রিপশন স্ট্যাটাস পরীক্ষা করতে DevicePolicyManager.getStorageEncryptionStatus() ব্যবহার করতে পারে।
আপনার অ্যাপটি যদি অ্যান্ড্রয়েড ৭.০ (এপিআই ২৪)-এর চেয়ে নিম্ন কোনো এপিআই লেভেলকে টার্গেট করে, এবং ডিভাইসটি ফুল-ডিস্ক এনক্রিপশন অথবা ডিরেক্ট বুট-সহ ফাইল-ভিত্তিক এনক্রিপশন ব্যবহার করে, তাহলে getStorageEncryptionStatus() ENCRYPTION_STATUS_ACTIVE রিটার্ন করে। এই উভয় ক্ষেত্রেই, ডেটা সর্বদা এনক্রিপ্টেড অবস্থায় সংরক্ষিত থাকে।
আপনার অ্যাপটি যদি অ্যান্ড্রয়েড ৭.০ (এপিআই ২৪) বা তার উচ্চতর সংস্করণকে টার্গেট করে, এবং ডিভাইসটি ফুল-ডিস্ক এনক্রিপশন ব্যবহার করে, তাহলে getStorageEncryptionStatus() ENCRYPTION_STATUS_ACTIVE রিটার্ন করে। আর ডিভাইসটি যদি ডিরেক্ট বুট সহ ফাইল-ভিত্তিক এনক্রিপশন ব্যবহার করে, তাহলে এটি ENCRYPTION_STATUS_ACTIVE_PER_USER রিটার্ন করে।
আপনি যদি অ্যান্ড্রয়েড ৭.০-কে লক্ষ্য করে কোনো ডিভাইস অ্যাডমিনিস্ট্রেশন অ্যাপ তৈরি করেন, তাহলে ডিভাইসটি এনক্রিপ্টেড কিনা তা নির্ধারণ করতে ENCRYPTION_STATUS_ACTIVE এবং ENCRYPTION_STATUS_ACTIVE_PER_USER উভয়ই পরীক্ষা করে দেখতে ভুলবেন না।
অতিরিক্ত কোডের নমুনা
DirectBoot স্যাম্পলটি এই পৃষ্ঠায় আলোচিত API-গুলোর ব্যবহার আরও বিশদভাবে প্রদর্শন করে।