當裝置處於開機狀態,但使用者未解鎖裝置時,Android 7.0 會在安全的「直接啟動」模式下執行。為支援這項功能,系統會提供兩個資料儲存位置:
- 憑證加密儲存空間,這是預設的儲存位置,只有在使用者解鎖裝置後才能使用。
- 裝置加密儲存空間,這是在直接啟動模式中,以及使用者解鎖裝置後皆可使用的儲存位置。
根據預設,應用程式不會在直接啟動模式下執行。如果您的應用程式必須在直接啟動模式下執行動作,您可以註冊要在這個模式執行的應用程式元件。需在直接啟動模式下執行的應用程式常見用途包括:
- 設有排程通知的應用程式,例如鬧鐘應用程式。
- 提供重要使用者通知的應用程式,例如簡訊應用程式。
- 提供無障礙服務的應用程式,例如 Talkback。
如果您的應用程式在直接啟動模式下執行時須存取資料,請使用裝置加密儲存空間。裝置加密儲存空間所含的資料是以金鑰加密,只有在裝置成功執行驗證開機程序後才能存取。
如果資料必須使用與使用者憑證相關聯的金鑰 (例如 PIN 碼或密碼) 加密,請使用憑證加密儲存空間。只有在使用者成功解鎖裝置後才能存取憑證加密儲存空間,但重新啟動裝置後就無法存取。如果使用者在裝置解鎖後啟用螢幕鎖定功能,依然可以存取憑證加密儲存空間。
要求在直接啟動模式下執行
如要在直接啟動模式或存取裝置加密儲存空間時執行應用程式,必須先向系統註冊應用程式元件。將元件標示為「加密感知」,即可向系統註冊應用程式。如要將元件標示為加密感知,請在資訊清單中將 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
例項。使用此結構定義的所有 Storage 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...
請只針對須在直接啟動模式下存取的資訊使用裝置加密儲存空間,不要將其做為一般用途的加密儲存空間。如果是私人使用者資訊,或不需要在直接啟動模式下存取的加密資料,請使用憑證加密儲存空間。
在使用者解鎖時收到通知
如果使用者重新啟動並解鎖裝置,您的應用程式可以改用憑證加密儲存空間,並使用仰賴使用者憑證的一般系統服務。
如要在使用者重新啟動並解鎖裝置時收到通知,請從執行中的元件註冊 BroadcastReceiver
,以便監聽解鎖通知訊息。如果使用者在啟動後解鎖裝置:
- 如果應用程式有需要立即取得通知的前景程序,請監聽
ACTION_USER_UNLOCKED
訊息。 - 如果應用程式僅使用可延遲收到通知的背景程序,請監聽
ACTION_BOOT_COMPLETED
訊息。
您可以呼叫 UserManager.isUserUnlocked()
,確認使用者是否已解鎖裝置。
遷移現有資料
如果使用者更新裝置以使用直接啟動模式,您可能會有需要遷移至裝置加密儲存空間的現有資料。使用 Context.moveSharedPreferencesFrom()
和 Context.moveDatabaseFrom()
,將目的地結構定義做為方法呼叫端,並將來源結構定義做為引數,即可在憑證加密儲存空間和裝置加密儲存空間之間,遷移偏好設定和資料庫資料。
請勿將使用者私人資訊 (例如密碼或授權權杖) 從憑證加密儲存空間遷移至裝置加密儲存空間。在思考要將哪些資料遷移到裝置加密儲存空間時,請運用您的判斷力做出最佳決定。在某些情況下,您可能需要管理兩個加密儲存庫中的個別資料組合。
測試可偵測加密功能的應用程式
請在啟用直接啟動模式的狀態下測試加密感知應用程式。
只要設定了螢幕鎖定憑證 (PIN 碼、解鎖圖案或密碼),大多數搭載新版 Android 的裝置就會啟用直接啟動模式,具體來說,凡是使用檔案型加密的裝置都是如此。如要檢查裝置是否使用檔案型加密,請執行下列殼層指令:
adb shell getprop ro.crypto.type
如果輸出結果是 file
,表示裝置已啟用檔案型加密。
在預設未使用檔案型加密的裝置上,可能會有其他測試直接啟動模式的選項:
-
部分裝置採用全磁碟加密 (
ro.crypto.type=block
),且搭載的 Android 版本介於 7.0 至 12,可以轉換成檔案型加密。方法有以下兩種:- 在 Android 手機上啟用「開發人員選項」,方法是依序前往「設定」>「關於手機」,然後輕觸「版本號碼」七次。接著依序前往「設定」>「開發人員選項」,選取「轉換成檔案加密」。
- 或者,您也可以執行下列殼層指令:
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),若裝置在直接啟動模式下使用全磁碟加密或檔案型加密,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 用法。