Android 7.0 以上版本支援檔案型加密 (FBE)。FBE 可讓您使用可以解鎖的不同金鑰來加密不同的檔案 以便獨立作業這些金鑰可用於加密檔案內容和檔案名稱。 使用 FBE 時,其他資訊如目錄版面配置、檔案大小 權限,以及建立/修改時間都不會加密。這些其他資訊統稱為檔案系統中繼資料。
Android 9 開始支援中繼資料加密。 透過中繼資料加密,啟動時的單一金鑰會加密任何項目 內容並未由 FBE 加密。這組金鑰受 Keymaster 保護, 會由驗證開機程序保護。
啟用 FBE 時,一律在採用儲存空間中啟用中繼資料加密。 您也可以在內部儲存空間中啟用中繼資料加密功能。搭載 Android 11 以上版本的裝置必須啟用內部儲存空間的中繼資料加密功能。
在內部儲存空間實作
您可以在新裝置的內部儲存空間上設定中繼資料加密,步驟如下:
設定 metadata
檔案系統、變更 init 序列,以及
在裝置的 fstab 檔案中啟用中繼資料加密。
必要條件
您只能在第一次格式化資料分割區時設定中繼資料加密功能。因此,這項功能僅適用於新裝置。這不是 OTA 應該變更。
如要加密中繼資料,您必須在核心中啟用 dm-default-key
模組。在 Android 11 以上版本中,
Android 通用核心版本支援 dm-default-key
4.14 以及更高版本。這個 dm-default-key
版本使用了硬體,
廠商獨立加密的架構,稱為 blk-crypto。
如要啟用 dm-default-key
,請使用:
CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_DM_DEFAULT_KEY=y
dm-default-key
使用內嵌加密硬體 (符合以下條件的硬體)
在資料傳輸至儲存裝置中,或從儲存裝置傳輸資料時,於
廣告。如果您「並未」使用內嵌加密硬體,則
啟用退回核心密碼編譯 API 的替代方案:
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
如果您未使用內嵌加密硬體,也應按照 FBE 說明文件中的建議,啟用任何可用的 CPU 加速功能。
在 Android 10 以下版本中,Android 通用核心不支援 dm-default-key
。因此,供應商必須實作 dm-default-key
。
設定中繼資料檔案系統
因為在中繼資料前,一律無法讀取使用者資料分區中的內容 當存在加密金鑰,分區表必須將 名為「中繼資料分區」儲存金鑰的 blob 確保這組金鑰安全無虞中繼資料分區應為 16MB。
fstab.hardware
必須包含中繼資料檔案系統的項目
掛接於該分區上,包括掛接到 /metadata
formattable
標記,以確保在啟動時格式化。
f2fs 檔案系統不適用於較小的分區;建議使用 ext4
。例如:
/dev/block/bootdevice/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard wait,check,formattable
為確保 /metadata
掛接點確實存在,請新增下列這一行
至 BoardConfig-common.mk
:
BOARD_USES_METADATA_PARTITION := true
init 序列的變更
使用中繼資料加密功能時,必須先執行 vold
,才能掛載 /data
。為確保在適當時間開始,請將下列節錄加入 init.hardware.rc
:
# We need vold early for metadata encryption on early-fs start vold
init 必須先在執行中並準備就緒,才能在 init 嘗試掛接
/data
。
init.hardware.rc
應已包含 mount_all
指令,可在 on
late-fs
段落中掛載 /data
。在這個行前,新增指令以執行
wait_for_keymaster
服務:
on late-fs … # Wait for keymaster exec_start wait_for_keymaster # Mount RW partitions which need run fsck mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late
開啟中繼資料加密功能
最後,將 keydirectory=/metadata/vold/metadata_encryption
新增至 userdata
的 fstab
項目的 fs_mgr_flags 欄。例如,完整的 fstab 行看起來可能像這樣:
/dev/block/bootdevice/by-name/userdata /data f2fs noatime,nosuid,nodev,discard,inlinecrypt latemount,wait,check,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized,keydirectory=/metadata/vold/metadata_encryption,quota,formattable
根據預設,內部儲存空間的中繼資料加密演算法為 AES-256-XTS。如要覆寫這項設定,請設定
metadata_encryption
選項,也包含在
fs_mgr_flags 資料欄:
- 在缺乏 AES 加速功能的裝置上,您可以設定
metadata_encryption=adiantum
來啟用 Adiantum 加密功能。 - 在支援硬體包裝金鑰的裝置上,您可以設定
metadata_encryption=aes-256-xts:wrappedkey_v0
(或等同於metadata_encryption=:wrappedkey_v0
,因為aes-256-xts
是預設演算法),將中繼資料加密金鑰包裝在硬體中。
因為 Android 中 dm-default-key
的核心介面已變更
11,您還必須確保
正確的PRODUCT_SHIPPING_API_LEVEL
值
device.mk
。舉例來說,如果裝置啟動時搭載的是 Android
11 (API 級別 30),device.mk
應
包含:
PRODUCT_SHIPPING_API_LEVEL := 30
您也可以設定下列系統屬性,無論運送 API 級別為何,一律強制使用新的 dm-default-key
API:
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.dm_default_key.options_format.version=2
驗證
如要驗證中繼資料加密功能是否已啟用且運作正常,請執行下列測試。請注意下方列出的常見問題。
測試
請先執行下列指令,確認已在內部儲存空間啟用中繼資料加密功能:
adb root
adb shell dmctl table userdata
畫面上應該會顯示類似以下的輸出內容:
Targets in the device-mapper table for userdata: 0-4194304: default-key, aes-xts-plain64 - 0 252:2 0 3 allow_discards sector_size:4096 iv_large_sectors
如果您在裝置的 fstab
中設定 metadata_encryption
選項,則輸出內容會與上述內容略有不同。舉例來說,如果您啟用 Adiantum 加密,則第三個
欄位為 xchacha12,aes-adiantum-plain64
,而非
aes-xts-plain64
。
接著,執行 vts_kernel_encryption_test ,驗證中繼資料加密和 FBE 的正確性:
atest vts_kernel_encryption_test
或:
vts-tradefed run vts -m vts_kernel_encryption_test
常見問題
在呼叫 mount_all
時,系統會掛載中繼資料加密的 /data
分區,init
會執行 vdc 工具。vdc 工具會透過 binder
連線至 vold
,設定使用中繼資料加密的裝置,並掛載分割區。在這個情境中
呼叫,init
遭到封鎖,嘗試讀取或設定
init
屬性區塊,直到 mount_all
結束為止。
如果在這個階段,vold
作業的任何部分直接或
間接禁止讀取或設定資源,造成死結結果。請務必確保 vold
能夠完成讀取鍵、與 Keymaster 互動,以及掛載資料目錄的工作,而無須進一步與 init
互動。
如果 mount_all
執行時未完全啟動 Keymaster,則不會
回應 vold
直到它讀到
init
,因此可確切導致說明的死結。將 exec_start wait_for_keymaster
放在相關 mount_all
呼叫之上,可確保 Keymaster 事先完全執行,進而避免發生此死結。
在可採用儲存空間上設定
從 Android 9 開始,這種中繼資料加密方式為 一律在採用儲存空間上啟用 啟用 FBE 時 (即使未啟用中繼資料加密功能) 內部儲存空間
在 Android 開放原始碼計畫中,採用中繼資料加密機制有兩種實作方式
storage:依據 dm-crypt
淘汰的項目,再依據更新的版本
在 dm-default-key
。為了確保正確實作
請確定您已為裝置設定正確的值
PRODUCT_SHIPPING_API_LEVEL
於 device.mk
。例如:
如果您的裝置搭載 Android 11 (API 級別 30),
device.mk
應包含:
PRODUCT_SHIPPING_API_LEVEL := 30
您也可以設定下列系統屬性,無論發布 API 級別為何,都能強制使用新的音量中繼資料加密方法 (以及新的預設 FBE 政策版本):
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.volume.metadata.method=dm-default-key \ ro.crypto.dm_default_key.options_format.version=2 \ ro.crypto.volume.options=::v2
目前的方法
在搭載 Android 11 以上版本的裝置上,可採用儲存空間上的中繼資料加密功能會使用 dm-default-key
核心模組,就像內部儲存空間一樣。瞭解核心設定的必要條件。
選項。請注意,在裝置內部儲存空間中運作的內嵌加密硬體可能無法在可採用的儲存空間中運作,因此可能需要 CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
。
根據預設,dm-default-key
磁碟區中繼資料加密方法
採用 AES-256-XTS 加密演算法和 4096 位元組加密編譯。您可以設定 ro.crypto.volume.metadata.encryption
系統屬性來覆寫演算法。這個屬性的值與上述 metadata_encryption
fstab 選項的語法相同。舉例來說,如果裝置缺少 AES 加速功能,您可以設定 ro.crypto.volume.metadata.encryption=adiantum
來啟用 Adiantum 加密功能。
舊版方法
在搭載 Android 10 以下版本的裝置上,可採用儲存空間上的中繼資料加密功能會使用 dm-crypt
核心模組,而非 dm-default-key
:
CONFIG_DM_CRYPT=y
與 dm-default-key
方法不同,dm-crypt
方法
會使檔案內容被加密兩次:一次使用 FBE 金鑰,另一次是使用
中繼資料加密金鑰這種雙重加密機制會降低效能,
不必達到中繼資料加密機制的安全性目標。自 Android 級別起,
確保 FBE 金鑰至少和中繼資料一樣不易入侵
加密金鑰供應商可自訂核心來避免重複
尤其是實作
allow_encrypt_override
選項,由 Android 傳遞至
系統屬性為 dm-crypt
ro.crypto.allow_encrypt_override
已設為 true
。
Android 通用核心不支援這些自訂項目。
根據預設,dm-crypt
磁碟區中繼資料加密方法會使用 AES-128-CBC 加密演算法,搭配 ESSIV 和 512 位元組加密區塊。您可以設定下列系統屬性 (也用於 FDE) 來覆寫此值:
ro.crypto.fde_algorithm
會選取中繼資料加密功能 演算法。可用的選項為aes-128-cbc
和adiantum
。只有在裝置缺少 AES 加速功能時,才能使用 Adiantum。ro.crypto.fde_sector_size
會選取加密部門大小。 可用的值包括 512、1024、2048 和 4096。如需 Adiantum 加密,請使用 4096。