转自:https://blog.csdn.net/dongyi1988/article/details/107048022
1、本文档简述
1.1、定义:
Full-disk encryption (FDE) 全盘加密android4.0引入
File-based encryption (FBE) 文件级加密 android7.0引入
1.2、学习目标:
1、熟悉android加密流程,挂载。
2、格式化加密userdata的部分数据。
3、假如user版本设备刚进入system就死机/重启,无法dump关键数据和信息进行分析。是否能够dump userdata分区并解密挂载分析。如果不能,为什么?(待深入研究)
2、预备知识
2.1、加密技术
https://www.cnblogs.com/redcoatjk/p/3822585.html按作用不同,文件加密和数字签名技术主要分为数据传输、数据存储、数据完整性的鉴别以及密钥管理技术4种。
1、数据传输加密技术是对传输中的数据流加密,常用的方法有线路加密和端对端加密两种。
2、数据存储加密技术目的是防止在存储环节上的数据失密,可分为密文存储和存取控制两种。
3、数据完整性鉴别技术是对介入信息的传送、存取、处理的人的身份和相关数据内容进行验证,达到保密的要求。
4、密钥管理技术是数据的加密技术通常是运用密钥对数据进行加密,这就涉及到了密钥的管理问题。
2.2、典型加密算法
2.2.1、基于“消息摘要”的主要算法
MD5、sha.1,主要特点密文固定长度、稍有改变密文完全不同、无法数据还原。所以用于验证数据的完整性。android中的使用例子OTA包传输使用的MD5,OTA差分升级使用的SHA256,DM-verity使用的HASH算法。
MD5算法原理https://blog.csdn.net/sinat_27933301/article/details/79538169
2.2.2、“对称/非对称密钥”加密算法
对称算法:DES算法,RC算法,AES算法,主要特点加密可逆,加密解密使用相同密钥。全盘加密,文件级加密使用的一般是AES算法。
非对称算法:RSA算法,主要特点是加密解密使用不同密钥。
公钥加密,私钥解密(加密传输);私钥签名,公钥验签(确认发送方,也可验证完整性,可以用于OTA包签名,secure boot,Verify boot,应用签名)。
https://www.jianshu.com/p/3331467d139f
签名、加密、证书的基本原理和理解
https://www.cnblogs.com/Caersi/p/6720789.html
AES算法原理https://blog.csdn.net/gulang03/article/details/81175854
RSA算法原理https://blog.csdn.net/u014044812/article/details/80866759
2.3、Linux加密工具
2.3.1对称算法
全盘加密
全盘加密工具使用https://blog.csdn.net/zhongbeida_xue/article/details/78550712#t18
示例
fallocate -l 64G /root/luks.vol //创建大文件
cryptsetup --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 10000 luksFormat /root/luks.vol //加密
cryptsetup luksOpen /root/luks.vol xxx //创建解密映射连接
ls /dev/mapper/
mkfs.ext4 /dev/mapper/xxx //给该块/文件创建文件系统
mkdir /mnt/xxx
mount /dev/mapper/xxx /mnt/xxx //挂载文件系统
df -hT
修改文件
umount /mnt/xxx //卸载
cryptsetup close xxx //关闭映射连接
文件系统加密
原理https://www.kernel.org/doc/html/latest/filesystems/fscrypt.html
文件级加密工具使用https://blog.csdn.net/zm_jack/article/details/78894980
sudo apt-get install ecryptfs-utils //安装控件
sudo mount -t ecryptfs real_path ecryptfs_mounted_path //以文件加密方式挂载文件
修改文件
sudo umount -t ecryptfs ecryptfs_test //卸载
以不同方式再挂载并修改文件
sudo mount -t ecryptfs real_path ecryptfs_mounted_path //以文件加密方式挂载文件
- 空间概念,配置时使用文件名加密,会有一个文件系统多个空间的感觉。
- 密钥管理机制,往不同目录挂载,使用不同密码或加密方式,/proc/keys 有证书就能直接访问各类不同加密方式的文件。
- 叠加加密,已经加密的文件目录可以再加密。
查看keys
cat /proc/keys | grep 【sig】
个人总结全盘加密和文件系统加密区别:
1、全盘加密只有一个密码,该密码正确解密后才可使用。文件级加密密码或参数不正确时也能挂载,如果之前加密的keyring存在,则可以读取文件,不存在则不能读取;写入时以新参数加密方式写入;
2、全盘加密磁盘上是已加密数据,看不到文件系统的,流程上是就需要先创建解密映射,然后挂载出文件系统(如果该磁盘不存在文件系统,只是bin文件就不需要再挂载了)。文件级加密已经存在文件系统,直接映射解密。
3、全盘加密与文件级加密都是透明加密,用户感觉不到加密;但文件级加密管理keyring,已经存在的解密keyring可以解密其它挂载地方;
4、文件级加密当使用Enable filename encryption (y/n) [n]: y可以达到使用不同空间的效果
5、文件级加密可以叠加加密。Ecryptfs工具可以叠加6次;
2.3.2 非对称算法
签名加密工具 openssl https://www.jianshu.com/p/2ac9ae269920
生成私钥
openssl genrsa -out privkey.pem 2048
生成公钥
openssl rsa -in privkey.pem -pubout -out pubkey.pem
echo penghuikang@foxmail.com > info.txt
公钥加密/私钥解密
使用公钥对明文进行加密
直接使用公钥加密
openssl rsautl -encrypt -in info.txt -inkey pubkey.pem -pubin -out info.txt.enc
使用证书中的公钥加密
openssl rsautl -encrypt -in info.txt -inkey pubkey.pem -certin -out info.txt.enc
使用私钥解密
openssl rsautl -decrypt -in info.txt.enc -inkey privkey.pem -out info_decrypt.txt
私钥签名/公钥验签
使用私钥对明文进行签名
openssl rsautl -sign -in info.txt -inkey privkey.pem -out info.txt.sign
使用公钥验签得到明文
openssl rsautl -verify -in info.txt.sign -inkey pubkey.pem -pubin -out info_verify.txt
3、Android 系统的加密应用
3.1、原理与流程
高通原理流程文档
80-PN330-9 Rev. A 、 80-NU861-1 J
3.2、FDE加密流程理解
Google官方文档
https://source.android.com/security/encryption/full-disk
若要加密、解密或清除 /data,/data 不得处于装载状态。但若要显示任何界面,框架都必须启动,而框架需要 /data 才能运行。为了解决这一冲突,/data 上会装载一个临时文件系统。通过该文件系统,Android 可以提示输入密码、显示进度或根据需要建议清除数据。
四种情况的流程:
A、使用 forceencrypt 加密新设备:首次启动时强制加密(从 Android L 开始)。
B、加密现有设备:由用户启动加密(Android K 及更低版本)。
C、启动无密码的已加密设备:启动未设置密码的已加密设备(适用于运行 Android 5.0 及更高版本的设备)。
D、启动设有密码的已加密设备:启动设置了密码的已加密设备。
图表 全盘加密流程图
流程不管如何,只需要知道以下关键点:
- 未解密时最小框架需要 /data 才能运行,所以tmpfs临时挂载;
- 未解密时不能装载/data,需要最小框架显示界面;UI主要作用是显示加密进度、输入密码、提示恢复出厂,因此其必须包括keymaster,恢复出厂,输入法,UI,加密库等东西。
- vold通过设置vold.decrypt状态,来触发init各类操作;vold 和 init 之间通过设置属性进行通信,vold.decrypt的状态如下:
trigger_encryption
trigger_restart_min_framework
trigger_default_encryption
trigger_shutdown_framework
trigger_post_fs_data
trigger_restart_framework
trigger_reset_main - vold.encrypt_progress加密进度。加密出错情况可通过此属性查看状态;
- 加密/解密工具,使用的密钥,密钥的存储。
主要函数system/vold/cryptfs.cpp/cryptfs_enable_internal(加密类型,密码,是否有UI)
decrypt_master_key //解密主钥
create_crypto_blk_dev //创建映射
create_encrypted_random_key //创建主钥
encrypt_master_key //加密主钥
put_crypt_ftr_and_key //放置密钥
init_empty_persist_data //初始化数据
save_persistent_data //保存
3.3、FBE加密流程与理解
FBE加密
https://source.android.com/security/encryption/file-based.html#fscrypt-encryption
Andorid 使用的是fscrypt文件系统加密工具。该工具最详细使用在github中。
https://github.com/google/fscrypt#getting-encryption-not-enabled-on-an-ext4-filesystem 但是还是资料太少,个人使用依然不方便。
Fscrypt使用需要注意:
1、sudo apt installl fscrypt libpam-fscrypt安装的没有lock命令,最好从github下载编译;
2、三种加密方式(随用户登陆,新密码,密钥文件),同时也有/proc/keys管理证书;在多用户情况下,/proc/keys内有相关管理证书即可透明访问;
3、在目录底下会创建.fscrypt文件夹保存policies和protectors信息;
4、不用挂载映射,但只能加密空目录,方便了开机。(假如已有文件,需要重新去写入。或存在参数可以加密已有文件);
android文件系统加密流程关键在fscrypt工具的理解,这里还是建议使用ecryptfs来理解文件系统加密,虽然ecryptfs 目前没有再维护,但资料比较多,使用方便,在理解文件系统加密方面更好用。
而android的文件系统解密调用流程起点是init.rc里的init_user0,其调用vold的load_all_de_keys加载DE密钥、fscrypt_unlock_user_key加载CE密钥。
FBE优点
能够直接挂载使用/data,DE密钥启动前就加入,可以直接启动
利用空间概念支持多位用户,并且能够互动
3.4、Android 加密的使用
3.4.1、查看设备加密方式:
FDE:ro.crypto.state = encrypted 和ro.crypto.type = block
FBE:ro.crypto.state = encrypted 和ro.crypto.type = file
3.4.2、源码配置:
MTK参考文档
[FAQ22664] [Encryption] How to configure FDE/FBE/FDE_TO_FBE
MTK相关变量
MTK_ENCRYPTION_DEFAULT_OFF
MTK_ENCRYPTION_FDE_TO_FBE
MTK_ENCRYPTION_TYPE_FILE
3.4.3、挂载表属性
fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]]
//文件加密 = 内容加密方式:文件名加密方式 :标记
/dev/block/by-name/userdata /data f2fs nodev,noatime,nosuid,errors=panic,inlinecrypt wait,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized
forceencrypt=footer //FDE加密 强制全盘加密,密钥存在页脚
fileencryption=ice //FBE加密 指定使用FSCRYPT_MODE_PRIVATE,文件内容加密模式,供应商实现。
fileencryption=adiantum
inlinecrypt_optimized //用户标记仅为每个 CE 或 DE 密钥派生一个文件内容加密密钥
inlinecrypt //装载选项
4、调试
问题1、已解
问题2、格式化加密userdata的部分数据
FDE
在解密后,装载/data前进行清除userdata的部分数据。最好在最小框架有个UI显示确认和进度。
FBE
该问题不存在难度,只需要在开机时删除目录,清除密钥。
问题3、假如user版本设备刚进入system就死机/重启,无法dump关键数据和信息进行分析。是否能够dump userdata分区并解密挂载分析。如果不能,为什么?(待深入研究)
FDE
3-1、尝试直接使用cryptsetup 和密码解密。-------失败
cryptsetup luksOpen userdata userdata失败, 可能加密类型与方式,加密工具,以及密钥问题。是否必须要keymaster?
3-2、dump dm-0后,使用该文件块直接挂载。 ----------成功
但是设备必须能够使用adb,必须root(当确定是userdata问题,可刷入userdebug版本来dump dm-0块设备),并且设备不会因为重启来打断dump(userdebug版本设置在adb和/data挂载后,定个停止启动)。
FBE
如果DE与CE策略搞混,高概率出问题。
如果硬件加密的话,暂时无思路解密。proc/keys都是临时密钥,取出来也不能用。
实际遇到的问题
fastboot -w恢复出厂不能开机
问题原因:当全盘加密使用forceencrypt=footer时,需要使用userdata分区的页脚16Kb的空间。Fastboot -w实际是获取userdata大小,制作文件系统,刷入设备。Fastboot工具制作文件系统时并不会给userdata保留16Kb的空间。
解决方法:方法一:forceencrypt=指定分区;方法二:bootloader设置userdata分区大小属性时,主动减少16Kb。
全盘加密时间较慢
问题原因:大容量或者userdata已经有数据的情况加密较慢,
无解,只有等,userdebug版本可以关闭全盘加密,加速工厂测试。
Google补丁降级提示输入密码
问题原因:防回滚保护的正常机制,
恢复出厂。
升级后无法解密/data
问题原因:升级后,keymaster 也升级,FDE流程中加密解密都用到Keymaster,导致无法解密/data
解决方法:替换回原来版本Keymaster解决。熟悉keymaster接口情况下可能有其他解决方法。