Android 7.0 จะทำงานในโหมด Direct Boot ที่ปลอดภัยเมื่อเปิดเครื่องแล้วแต่ผู้ใช้ยังไม่ได้ปลดล็อกอุปกรณ์ ระบบจึงมีตำแหน่งที่เก็บข้อมูล 2 แห่งเพื่อรองรับการทำงานนี้ ได้แก่
- พื้นที่เก็บข้อมูลที่เข้ารหัสด้วยข้อมูลเข้าสู่ระบบ ซึ่งเป็นตำแหน่งที่เก็บข้อมูลเริ่มต้น และจะใช้ได้ก็ต่อเมื่อผู้ใช้ปลดล็อกอุปกรณ์แล้วเท่านั้น
- พื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์ ซึ่งเป็นตำแหน่งที่เก็บข้อมูลที่ใช้ได้ทั้ง ในโหมด Direct Boot และหลังจากที่ผู้ใช้ปลดล็อกอุปกรณ์แล้ว
โดยค่าเริ่มต้น แอปจะไม่ทำงานในโหมด Direct Boot หากแอปต้องดำเนินการในโหมด Direct Boot คุณสามารถลงทะเบียนคอมโพเนนต์ของแอปให้ทำงานในโหมดนี้ได้ กรณีการใช้งานทั่วไปบางกรณีที่แอปต้องทำงานในโหมด Direct Boot ได้แก่
- แอปที่มีการแจ้งเตือนที่กำหนดเวลาไว้ เช่น แอปนาฬิกาปลุก
- แอปที่แสดงการแจ้งเตือนที่สำคัญแก่ผู้ใช้ เช่น แอป SMS
- แอปที่ให้บริการการช่วยเหลือพิเศษ เช่น Talkback
หากแอปต้องเข้าถึงข้อมูลขณะทำงานในโหมด Direct Boot ให้ใช้พื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์ พื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์จะมีข้อมูลที่เข้ารหัสด้วยคีย์ที่ใช้ได้ก็ต่อเมื่ออุปกรณ์ทำการบูตที่ยืนยันแล้วสำเร็จ
สำหรับข้อมูลที่ต้องเข้ารหัสด้วยคีย์ที่เชื่อมโยงกับข้อมูลเข้าสู่ระบบของผู้ใช้ เช่น PIN หรือรหัสผ่าน ให้ใช้พื้นที่เก็บข้อมูลที่เข้ารหัสด้วยข้อมูลเข้าสู่ระบบ พื้นที่เก็บข้อมูลที่เข้ารหัสด้วยข้อมูลเข้าสู่ระบบจะใช้ได้หลังจากที่ผู้ใช้ปลดล็อกอุปกรณ์สำเร็จแล้วและจนกว่าผู้ใช้จะรีสตาร์ทอุปกรณ์ หากผู้ใช้เปิดใช้หน้าจอล็อกหลังจากปลดล็อกอุปกรณ์ พื้นที่เก็บข้อมูลที่เข้ารหัสด้วยข้อมูลเข้าสู่ระบบจะยังคงใช้ได้
ขอสิทธิ์เข้าถึงเพื่อทำงานในระหว่างการบูตโดยตรง
แอปต้องลงทะเบียนคอมโพเนนต์กับระบบก่อนจึงจะทำงานในโหมด Direct Boot หรือเข้าถึงพื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์ได้ แอปจะลงทะเบียนกับระบบโดยทำเครื่องหมายคอมโพเนนต์เป็น encryption aware หากต้องการทำเครื่องหมายคอมโพเนนต์เป็น encryption aware ให้ตั้งค่าแอตทริบิวต์ android:directBootAware เป็น "จริง" ในไฟล์ Manifest
คอมโพเนนต์ encryption aware สามารถลงทะเบียนเพื่อรับข้อความประกาศ ACTION_LOCKED_BOOT_COMPLETED จากระบบเมื่ออุปกรณ์รีสตาร์ท เมื่อถึงจุดนี้ พื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์จะพร้อมใช้งาน และคอมโพเนนต์ของคุณจะสามารถทำงานที่ต้องเรียกใช้ในโหมด Direct Boot ได้ เช่น การทริกเกอร์การปลุกที่กำหนดเวลาไว้
ข้อมูลโค้ดต่อไปนี้เป็นตัวอย่างวิธีลงทะเบียน BroadcastReceiver เป็น encryption aware และเพิ่มตัวกรอง Intent สำหรับ ACTION_LOCKED_BOOT_COMPLETED ในไฟล์ Manifest ของแอป
<receiver android:directBootAware="true" > ... <intent-filter> <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" /> </intent-filter> </receiver>
เมื่อผู้ใช้ปลดล็อกอุปกรณ์แล้ว คอมโพเนนต์ทั้งหมดจะเข้าถึงได้ทั้งพื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์และพื้นที่เก็บข้อมูลที่เข้ารหัสด้วยข้อมูลเข้าสู่ระบบ
เข้าถึงพื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์
หากต้องการเข้าถึงพื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์ ให้สร้างอินสแตนซ์ที่ 2
Context โดยเรียกใช้
Context.createDeviceProtectedStorageContext() การเรียกใช้ 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 เท่านั้น อย่าใช้พื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์เป็นพื้นที่เก็บข้อมูลที่เข้ารหัสอเนกประสงค์ สำหรับข้อมูลส่วนตัวของผู้ใช้หรือข้อมูลที่เข้ารหัสซึ่งไม่จำเป็นต้องใช้ในโหมด Direct Boot ให้ใช้พื้นที่เก็บข้อมูลที่เข้ารหัสด้วยข้อมูลเข้าสู่ระบบ
รับการแจ้งเตือนเมื่อผู้ใช้ปลดล็อก
เมื่อผู้ใช้ปลดล็อกอุปกรณ์หลังจากรีสตาร์ท แอปของคุณจะเปลี่ยนไปเข้าถึงพื้นที่เก็บข้อมูลที่เข้ารหัสด้วยข้อมูลเข้าสู่ระบบและใช้บริการระบบปกติที่ขึ้นอยู่กับข้อมูลเข้าสู่ระบบของผู้ใช้ได้
หากต้องการรับการแจ้งเตือนเมื่อผู้ใช้ปลดล็อกอุปกรณ์หลังจากรีบูต ให้ลงทะเบียน BroadcastReceiver จากคอมโพเนนต์ที่ทำงานอยู่เพื่อรับฟังข้อความการแจ้งเตือนการปลดล็อก เมื่อผู้ใช้ปลดล็อกอุปกรณ์หลังจากบูต ให้ทำดังนี้
- หากแอปมีกระบวนการเบื้องหน้าซึ่งต้องได้รับการแจ้งเตือนทันที ให้รับฟังข้อความ
ACTION_USER_UNLOCKED - หากแอปใช้เฉพาะกระบวนการเบื้องหลังที่สามารถดำเนินการกับการแจ้งเตือนที่ล่าช้าได้ ให้รับฟังข้อความ
ACTION_BOOT_COMPLETED
หากผู้ใช้ปลดล็อกอุปกรณ์แล้ว คุณจะตรวจสอบได้โดยเรียกใช้ UserManager.isUserUnlocked()
ย้ายข้อมูลที่มีอยู่
หากผู้ใช้อัปเดตอุปกรณ์ให้ใช้โหมด Direct Boot คุณอาจมีข้อมูลที่มีอยู่ซึ่งต้องย้ายไปยังพื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์ ใช้ Context.moveSharedPreferencesFrom() และ Context.moveDatabaseFrom() โดยให้บริบทปลายทางเป็นผู้เรียกเมธอดและบริบทต้นทางเป็นอาร์กิวเมนต์ เพื่อย้ายข้อมูลการกำหนดค่าและข้อมูลฐานข้อมูลระหว่างพื้นที่เก็บข้อมูลที่เข้ารหัสด้วยข้อมูลเข้าสู่ระบบกับพื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์
อย่าย้ายข้อมูลส่วนตัวของผู้ใช้ เช่น รหัสผ่านหรือโทเค็นการให้สิทธิ์ จากพื้นที่เก็บข้อมูลที่เข้ารหัสด้วยข้อมูลเข้าสู่ระบบไปยังพื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์ โปรดใช้วิจารณญาณในการตัดสินใจว่าจะย้ายข้อมูลอื่นๆ ไปยังพื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์หรือไม่ ในบางสถานการณ์ คุณอาจต้องจัดการชุดข้อมูลแยกกันในพื้นที่เก็บข้อมูลที่เข้ารหัส 2 แห่ง
ทดสอบแอป encryption aware
ทดสอบแอป encryption aware โดยเปิดใช้โหมด Direct Boot
อุปกรณ์ส่วนใหญ่ที่ใช้ Android เวอร์ชันล่าสุดจะเปิดใช้โหมด Direct Boot ทุกครั้งที่ตั้งค่าข้อมูลเข้าสู่ระบบของหน้าจอล็อก (PIN, รูปแบบ หรือรหัสผ่าน) โดยเฉพาะอย่างยิ่งในอุปกรณ์ทั้งหมดที่ใช้การเข้ารหัสตามไฟล์ หากต้องการตรวจสอบว่าอุปกรณ์ใช้การเข้ารหัสตามไฟล์หรือไม่ ให้เรียกใช้คำสั่งเชลล์ต่อไปนี้
adb shell getprop ro.crypto.type
หากเอาต์พุตเป็น file แสดงว่าอุปกรณ์เปิดใช้การเข้ารหัสตามไฟล์
ในอุปกรณ์ที่ไม่ได้ใช้การเข้ารหัสตามไฟล์โดยค่าเริ่มต้น อาจมีตัวเลือกอื่นๆ สำหรับการทดสอบโหมด Direct Boot ดังนี้
-
อุปกรณ์บางเครื่องที่ใช้การเข้ารหัสทั้งดิสก์ (
ro.crypto.type=block) และใช้ Android 7.0 ถึง Android 12 สามารถแปลงเป็นการเข้ารหัสตาม ไฟล์ได้ ทำได้ 2 วิธีดังนี้- ในอุปกรณ์ ให้เปิดใช้ตัวเลือกสำหรับนักพัฒนาแอป หากยังไม่ได้เปิดใช้ โดยไปที่การตั้งค่า > เกี่ยวกับโทรศัพท์ แล้วแตะหมายเลขบิลด์ 7 ครั้ง จากนั้นไปที่การตั้งค่า > ตัวเลือกสำหรับนักพัฒนาแอป แล้วเลือกแปลงเป็นการเข้ารหัสไฟล์
- หรือเรียกใช้คำสั่งเชลล์ต่อไปนี้
adb reboot-bootloaderfastboot --wipe-and-use-fbe
คำเตือน: การแปลงเป็นการเข้ารหัสตามไฟล์ไม่ว่าจะใช้วิธีใดก็ตามจะล้างข้อมูลผู้ใช้ทั้งหมดในอุปกรณ์
-
อุปกรณ์ที่ใช้ Android 13 หรือต่ำกว่ารองรับโหมด Direct Boot "จำลอง" ซึ่งใช้สิทธิ์ในไฟล์เพื่อจำลองผลลัพธ์ของไฟล์ที่เข้ารหัสซึ่งถูกล็อกและปลดล็อก ใช้โหมดจำลอง ระหว่างการพัฒนาเท่านั้น เนื่องจากอาจทำให้ข้อมูลรั่วไหลได้ หากต้องการเปิดใช้โหมด Direct Boot จำลอง ให้ตั้งค่ารูปแบบการล็อกในอุปกรณ์ เลือก "ไม่เป็นไร" หากระบบแจ้งให้ตั้งค่าหน้าจอการเริ่มต้นระบบที่ปลอดภัยเมื่อตั้งค่ารูปแบบการล็อก แล้วเรียกใช้คำสั่งเชลล์ต่อไปนี้
adb shell sm set-emulate-fbe true
หากต้องการปิดโหมด Direct Boot จำลอง ให้เรียกใช้คำสั่งเชลล์ต่อไปนี้
adb shell sm set-emulate-fbe false
การเรียกใช้คำสั่งใดคำสั่งหนึ่งต่อไปนี้จะทำให้เครื่องรีบูต
ตรวจสอบสถานะการเข้ารหัสของนโยบายอุปกรณ์
แอปการดูแลระบบอุปกรณ์สามารถใช้ DevicePolicyManager.getStorageEncryptionStatus() เพื่อตรวจสอบสถานะการเข้ารหัสปัจจุบันของอุปกรณ์
หากแอปกำหนดเป้าหมายเป็นระดับ API ต่ำกว่า Android 7.0 (API 24) getStorageEncryptionStatus() จะแสดงผล ENCRYPTION_STATUS_ACTIVE หากอุปกรณ์ใช้การเข้ารหัสดิสก์เต็มรูปแบบหรือการเข้ารหัสตามไฟล์ที่มีการบูตโดยตรง ในทั้ง 2 กรณีนี้ ระบบจะจัดเก็บข้อมูลที่เข้ารหัสไว้เสมอ
หากแอปกำหนดเป้าหมายเป็น 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 ที่กล่าวถึงในหน้านี้เพิ่มเติม