深入理解Android之设备加密Device Encryption
概念
加密是使用对称加密密钥对 Android 设备上的所有用户数据进行编码的过程。设备经过加密后,所有由用户创建的数据在存入磁盘之前都会自动加密,并且所有读取操作都会在将数据返回给调用进程之前自动解密数据。加密可确保未经授权方在尝试访问相应数据时无法进行读取。
Android 有两种设备加密方法,即文件级加密和全盘加密。
文件级加密
Android 7.0 及更高版本支持文件级加密。采用文件级加密时,可以使用不同的密钥对不同的文件进行加密,也可以对加密文件单独解密
全盘加密
搭载 Android 10 及更高版本的新设备上不允许使用全盘加密。请在新设备上使用文件级加密
Android 5.0 到 Android 9 支持全盘加密。全盘加密是使用单个密钥(由用户的设备密码加以保护)来保护设备的整个用户数据分区。在启动时,用户必须先提供其凭据,然后才能访问磁盘的任何部分。
加密配置
./rockchip/rk3399/rk3399_all.mk
./rockchip/rk3399/rk3399_all.mk:BUILD_WITH_FORCEENCRYPT := true
device/rockchip/rk3399/device.mk
ifeq ($(BUILD_WITH_FORCEENCRYPT),true)
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/fstab.rk30board.bootmode.forceencrypt.unknown:root/fstab.rk30board.bootmode.unknown \
$(LOCAL_PATH)/fstab.rk30board.bootmode.forceencrypt.emmc:root/fstab.rk30board.bootmode.emmc \
$(LOCAL_PATH)/fstab.rk30board.bootmode.forceencrypt.nvme:root/fstab.rk30board.bootmode.nvme
else
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/fstab.rk30board.bootmode.unknown:root/fstab.rk30board.bootmode.unknown \
$(LOCAL_PATH)/fstab.rk30board.bootmode.emmc:root/fstab.rk30board.bootmode.emmc \
$(LOCAL_PATH)/fstab.rk30board.bootmode.nvme:root/fstab.rk30board.bootmode.nvme
endif
fstab.rk30board.bootmode.forceencrypt.emmc VS fstab.rk30board.bootmode.emmc
- 差异点1: 是否支持system分区完整性校验 verify=/dev/block/platform/fe330000.sdhci/by-name/verity_mode
- 差异点2: 是否强制全盘加密 forceencrypt=/metadata/key_file(强制) encryptable=/metadata/key_file(非强制)
***system 分区***
/dev/block/platform/fe330000.sdhci/by-name/system /system ext4 ro,noatime,nodiratime,noauto_da_alloc wait,resize,verify=/dev/block/platform/fe330000.sdhci/by-name/verity_mode
# use this line below instead to enable verity
#/dev/block/platform/fe330000.sdhci/by-name/system /system ext4 ro,noatime,nodiratime,noauto_da_alloc wait,check,verify
/dev/block/platform/fe330000.sdhci/by-name/cache /cache ext4 noatime,nodiratime,nosuid,nodev,noauto_da_alloc,discard wait,check
/dev/block/platform/fe330000.sdhci/by-name/metadata /metadata ext4 noatime,nodiratime,nosuid,nodev,noauto_da_alloc,discard wait,check
***userdata 分区加密forceencrypt=/metadata/key_file**
#data for ext4
/dev/block/platform/fe330000.sdhci/by-name/userdata /data ext4 noatime,nodiratime,nosuid,nodev,noauto_da_alloc,discard,errors=panic,dirsync wait,check,forceencrypt=/metadata/key_file
/dev/block/platform/fe330000.sdhci/by-name/misc /misc emmc defaults defaults
# sdcard
/devices/platform/fe320000.dwmmc/mmc_host* auto auto defaults voldmanaged=sdcard1:auto,encryptable=userdata
# for usb2.0
/devices/platform/*.usb* auto vfat defaults voldmanaged=usb:auto
# for usb3.0
/devices/platform/usb@*/*.dwc3* auto vfat defaults voldmanaged=usb:auto
# pcie
/devices/platform/*.pcie* auto vfat defaults voldmanaged=pcie:auto
/dev/block/zram0 none swap defaults zramsize=533413200
WIF VS Firefly
主要差异在于 forceencrypt 和 encryptable 这两个选项。forceencrypt 强制加密整个分区,而 encryptable 允许在加密文件系统中进行加密处理,但可能不强制全盘加密
**WIF**
/dev/block/platform/fe330000.sdhci/by-name/userdata /data ext4 noatime,nodiratime,nosuid,nodev,noauto_da_alloc,discard,errors=panic,dirsync wait,check,forceencrypt=/metadata/key_file
**Firefly**
/dev/block/platform/fe330000.sdhci/by-name/userdata /data ext4 noatime,nodiratime,nosuid,nodev,noauto_da_alloc,discard,errors=panic,dirsync wait,check,encryptable=/metadata/key_file
加密失败
src/com/android/settings/CryptKeeper.java
public class CryptKeeper extends Activity implements TextView.OnEditorActionListener,
OnKeyListener, OnTouchListener, TextWatcher {
private void updateProgress() {
final String state = SystemProperties.get("vold.encrypt_progress");
if ("error_partially_encrypted".equals(state)) {
showFactoryReset(false);
return;
}
}
private void showFactoryReset(final boolean corrupt) {
// Show the reset button, failure text, and a divider
final Button button = (Button) findViewById(R.id.factory_reset);
button.setVisibility(View.VISIBLE);
}
}