รองรับโหมดเปิดเครื่องโดยตรง

Android 7.0 ทำงานในโหมดเปิดเครื่องโดยตรงที่ปลอดภัย เมื่อเปิดอุปกรณ์แล้ว แต่ผู้ใช้ไม่ได้ปลดล็อก อุปกรณ์ ระบบมีที่เก็บข้อมูล 2 แห่งสำหรับข้อมูลเพื่อรองรับการดำเนินการนี้ ดังนี้

  • พื้นที่เก็บข้อมูลเข้าสู่ระบบที่เข้ารหัส ซึ่งเป็นตำแหน่งพื้นที่เก็บข้อมูลเริ่มต้น และใช้งานได้หลังจากที่ผู้ใช้ปลดล็อกอุปกรณ์แล้วเท่านั้น
  • พื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์ ซึ่งเป็นตำแหน่งพื้นที่เก็บข้อมูลที่ใช้ได้ทั้ง ในระหว่างโหมดการเปิดเครื่องโดยตรง และหลังจากที่ผู้ใช้ปลดล็อกอุปกรณ์แล้ว

โดยค่าเริ่มต้น แอปจะไม่ทำงานระหว่างโหมด Direct Boot หากแอปของคุณต้องดำเนินการระหว่างโหมด Direct Boot คุณสามารถลงทะเบียน คอมโพเนนต์ของแอปที่จะเรียกใช้ในโหมดนี้ Use Case ที่พบบ่อยบางส่วน สำหรับแอปที่จำเป็นต้องทำงานระหว่างโหมดการเปิดเครื่องโดยตรง ได้แก่

  • แอปที่มีการแจ้งเตือนที่กำหนดเวลาไว้ เช่น นาฬิกาปลุก แอป
  • แอปที่ให้การแจ้งเตือนที่สำคัญแก่ผู้ใช้ เช่น แอป SMS
  • แอปที่ให้บริการการช่วยเหลือพิเศษ เช่น TalkBack

หากแอปจำเป็นต้องเข้าถึงข้อมูลขณะทำงานในโหมดการบูตโดยตรง ให้ใช้พื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์ ที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์มีข้อมูล เข้ารหัสด้วยคีย์ที่ใช้ได้หลังจากที่อุปกรณ์ดำเนินการ การเปิดเครื่องที่ได้รับการยืนยันสำเร็จ

สำหรับข้อมูลที่ต้องเข้ารหัสด้วยคีย์ที่เชื่อมโยงกับผู้ใช้ ข้อมูลเข้าสู่ระบบ เช่น PIN หรือรหัสผ่าน ใช้พื้นที่เก็บข้อมูลที่เข้ารหัสด้วยข้อมูลเข้าสู่ระบบ พื้นที่เก็บข้อมูลที่เข้ารหัสข้อมูลเข้าสู่ระบบจะพร้อมใช้งานหลังจากที่ผู้ใช้ปลดล็อกอุปกรณ์สำเร็จและจนกว่าผู้ใช้จะรีสตาร์ทอุปกรณ์ หาก ผู้ใช้เปิดใช้หน้าจอล็อกหลังจากปลดล็อกอุปกรณ์ คุณจะยังใช้พื้นที่เก็บข้อมูลที่เข้ารหัสข้อมูลเข้าสู่ระบบได้

ขอสิทธิ์เข้าถึงเพื่อทำงานระหว่างการเปิดเครื่องโดยตรง

แอปต้องลงทะเบียนคอมโพเนนต์กับระบบก่อนจึงจะทำงานในโหมดการบูตโดยตรงหรือเข้าถึงพื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์ได้ แอปลงทะเบียนกับระบบโดยทำเครื่องหมายคอมโพเนนต์เป็น การเข้ารหัส หากต้องการทําเครื่องหมายคอมโพเนนต์ว่ารองรับการเข้ารหัส ให้ตั้งค่าแอตทริบิวต์ android:directBootAware เป็น true ในไฟล์ Manifest

คอมโพเนนต์ที่ทราบเกี่ยวกับการเข้ารหัสสามารถลงทะเบียนเพื่อรับACTION_LOCKED_BOOT_COMPLETEDข้อความประกาศจากระบบเมื่ออุปกรณ์รีสตาร์ท อุปกรณ์มีการเข้ารหัส ณ จุดนี้ และคอมโพเนนต์สามารถดำเนินงานที่จำเป็น ทำงานระหว่างโหมดการเปิดเครื่องโดยตรง เช่น เรียกใช้การปลุกที่ตั้งเวลาไว้

ข้อมูลโค้ดต่อไปนี้เป็นตัวอย่างวิธีลงทะเบียน BroadcastReceiver ว่าเป็นแอปที่รองรับการเข้ารหัส และเพิ่มตัวกรอง Intent สําหรับ ACTION_LOCKED_BOOT_COMPLETED ในไฟล์ Manifest ของแอป

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

เมื่อผู้ใช้ปลดล็อกอุปกรณ์แล้ว คอมโพเนนต์ทั้งหมดจะสามารถเข้าถึงทั้ง อุปกรณ์จัดเก็บข้อมูลที่เข้ารหัส รวมถึงพื้นที่เก็บข้อมูลเข้าสู่ระบบที่เข้ารหัส

เข้าถึงพื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์

หากต้องการเข้าถึงพื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์ ให้สร้างอินสแตนซ์Contextที่ 2 โดยการเรียกใช้Context.createDeviceProtectedStorageContext() API พื้นที่เก็บข้อมูลทั้งหมด การโทรที่ดำเนินการโดยใช้บริบทนี้จะเข้าถึงพื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์ ตัวอย่างต่อไปนี้เข้าถึงที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์และเปิด ไฟล์ข้อมูลแอป:

KotlinJava
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() โดยมีบริบทปลายทางเป็นตัวเรียกเมธอดและใช้บริบทต้นทางเป็นอาร์กิวเมนต์สำหรับย้ายข้อมูลค่ากำหนดและฐานข้อมูล ข้อมูลระหว่างพื้นที่เก็บข้อมูลที่เข้ารหัสข้อมูลเข้าสู่ระบบและพื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์

โปรดอย่าย้ายข้อมูลส่วนตัวของผู้ใช้ เช่น รหัสผ่านหรือโทเค็นการให้สิทธิ์ ออกจาก พื้นที่เก็บข้อมูลเข้าสู่ระบบที่เข้ารหัสไปยังพื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์ ใช้วิจารณญาณของคุณเองเมื่อตัดสินใจว่าจะย้ายข้อมูลอื่นๆ ใดไปยังพื้นที่เก็บข้อมูลที่เข้ารหัสของอุปกรณ์ ในบางกรณี คุณอาจต้องจัดการ ชุดข้อมูลแยกกันในที่เก็บที่เข้ารหัส 2 แห่ง

ทดสอบแอปที่ทราบเกี่ยวกับการเข้ารหัส

ทดสอบแอปที่รู้จักการเข้ารหัสโดยเปิดใช้โหมดการบูตโดยตรง

อุปกรณ์ส่วนใหญ่ที่ใช้ Android เวอร์ชันล่าสุดจะเปิดใช้โหมดการเปิดเครื่องโดยตรง เมื่อมีการตั้งค่าข้อมูลเข้าสู่ระบบของหน้าจอล็อก (PIN, รูปแบบ หรือรหัสผ่าน) กล่าวโดยละเอียดคือ กรณีนี้เกิดขึ้นในอุปกรณ์ทั้งหมดที่ใช้การเข้ารหัสตามไฟล์ หากต้องการตรวจสอบว่าอุปกรณ์ใช้การเข้ารหัสตามไฟล์หรือไม่ ให้เรียกใช้คำสั่งเชลล์ต่อไปนี้

adb shell getprop ro.crypto.type

หากเอาต์พุตคือ file แสดงว่าอุปกรณ์เปิดใช้การเข้ารหัสตามไฟล์

ในอุปกรณ์ที่ไม่ได้ใช้การเข้ารหัสตามไฟล์โดยค่าเริ่มต้น อาจมีตัวเลือกอื่นๆ สำหรับการทดสอบโหมดการบูตโดยตรง ดังนี้

  • อุปกรณ์บางเครื่องที่ใช้การเข้ารหัสแบบ Fullดิสก์ (ro.crypto.type=block) และใช้ Android 7.0 ถึง แปลงเป็น Android 12 ตามไฟล์ได้ การเข้ารหัส ซึ่งทำได้ 2 วิธีดังนี้

      คำเตือน: ทั้ง 2 วิธีในการแปลงเป็นการเข้ารหัสตามไฟล์จะล้างข้อมูลผู้ใช้ทั้งหมดในอุปกรณ์

    • ในอุปกรณ์ ให้เปิดใช้ตัวเลือกสำหรับนักพัฒนาแอปหากยังไม่ได้เปิดใช้ โดยไปที่การตั้งค่า > เกี่ยวกับโทรศัพท์ แล้วแตะหมายเลขบิลด์ 7 ครั้ง จากนั้นไปที่การตั้งค่า > ตัวเลือกสำหรับนักพัฒนาแอป แล้วเลือกแปลงเป็นการเข้ารหัสไฟล์
    • หรือเรียกใช้คำสั่ง Shell ต่อไปนี้
      adb reboot-bootloader
      fastboot --wipe-and-use-fbe
      
  • อุปกรณ์ที่ใช้ Android 13 หรือต่ำกว่ารองรับโหมดการบูตโดยตรงแบบ "จำลอง" ที่ใช้สิทธิ์ของไฟล์เพื่อจำลองผลของการล็อกและปลดล็อกไฟล์ที่เข้ารหัส ใช้เฉพาะโหมดจำลอง ระหว่างการพัฒนา อาจทำให้ข้อมูลสูญหายได้ หากต้องการเปิดใช้โหมดการบูตโดยตรงที่จำลอง ให้ตั้งค่ารูปแบบล็อกในอุปกรณ์ เลือก "ไม่ขอบคุณ" หากได้รับข้อความแจ้งให้ตั้งค่าหน้าจอเริ่มต้นที่ปลอดภัยเมื่อตั้งค่ารูปแบบล็อก จากนั้นเรียกใช้คำสั่ง Shell ต่อไปนี้

    adb shell sm set-emulate-fbe true
    

    หากต้องการปิดโหมด Direct Boot ที่จำลอง ให้เรียกใช้ Shell ต่อไปนี้ คำสั่ง:

    adb shell sm set-emulate-fbe false
    

    การใช้คำสั่งใดคำสั่งหนึ่งเหล่านี้จะทำให้อุปกรณ์รีบูต

ตรวจสอบสถานะการเข้ารหัสนโยบายด้านอุปกรณ์

แอปการดูแลระบบอุปกรณ์สามารถใช้ได้ DevicePolicyManager.getStorageEncryptionStatus() เพื่อตรวจสอบสถานะการเข้ารหัสปัจจุบันของอุปกรณ์

หากแอปกำหนดเป้าหมายระดับ API ต่ำกว่า Android 7.0 (API 24) getStorageEncryptionStatus() ทำรีเทิร์น ENCRYPTION_STATUS_ACTIVE หากอุปกรณ์ใช้การเข้ารหัสทั้งดิสก์ หรือการเข้ารหัสตามไฟล์ด้วย Direct Boot ในทั้ง 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 ที่ครอบคลุมในหน้านี้เพิ่มเติม