一、原理简介
linux内核支持实现文件级加解密系统,因此如果不考虑密钥的安全存储,只需要开启相关内核配置,并集成fscrypt用户空间工具,即可实现文件级加解密。
fscrypt通过hook文件系统的方式实现文件级加密,加解密逻辑直接嵌入文件操作过程。
二、用户空间工具
2.1. C语言简易版
fscryptctl是一个精简的fscrypt用户空间工具,适合用来实现实验性质的文件系统加解密系统,开放源代码地址为:https://github.com/google/fscryptctl。
2.2. go语言完整版
fscrypt go语言完整版包含了复杂的fscrypt工具和命令,适合在功能强大的PC中集成,开放源代码地址为:https://github.com/google/fscrypt。
三、内核配置
打开内核配置选项CONFIG_FS_ENCRYPTION:
四、编译方式
在Makefile中配置以arm64为目标平台的gcc和ld,如下所示:
CC := aarch64-linux-gnu-gcc LD := aarch64-linux-gnu-ld |
五、验证
5.1. 实现加密分区
1. 选择log分区为fscrypt作用分区,确认块设备编号
root@emulator:/userdata# mount | grep log /dev/block/platform/by-name/log on /log type ext4 (rw,seclabel,noatime,discard) root@emulator:/dev/block/platform/by-name# ls -l | grep log lrwxrwxrwx 1 root root 15 Jan 1 08:00 log -> /dev/mmcblk0p30 |
2. 将log分区文件系统设为可加密类型
root@emulator:/dev/block/platform/by-name# tune2fs -O encrypt /dev/mmcblk0p30 tune2fs 1.45.3 (14-Jul-2019) |
3. 生成随机密钥
dd if=/dev/urandom of=/tmp/key bs=1 count=64 64+0 records in 64+0 records out |
4. 为文件系统关联密钥
root@emulator:/userdata# ./fscryptctl add_key /log < /tmp/key a290ce05e9566ad81acda348a2b906ab |
5. 查看密钥状态
root@emulator:/userdata# ./fscryptctl key_status a290ce05e9566ad81acda348a2b906ab /log Present (user_count=1, added_by_self) |
6. 设置加密策略
./fscryptctl set_policy a290ce05e9566ad81acda348a2b906ab /log/enc |
7. 查看加密策略
root@emulator:/userdata# ./fscryptctl get_policy /log/enc Encryption policy for /log/enc: Policy version: 2 Master key identifier: a290ce05e9566ad81acda348a2b906ab Contents encryption mode: AES-256-XTS Filenames encryption mode: AES-256-CTS Flags: PAD_32 |
8. 构造文件和目录
root@emulator:/userdata# echo This is the message! > /log/enc/message root@emulator:/userdata# mkdir /log/enc/testdir root@emulator:/userdata# cat /log/enc/message This is the message! root@emulator:/userdata# ls /log/enc message testdir |
5.2. 测试加密效果
1. 删除密钥,测试文件的加密效果
# 删除密钥 root@emulator:/userdata# ./fscryptctl remove_key a290ce05e9566ad81acda348a2b906ab /log warning: some files using this key are still in-use # 查看密钥状态 root@emulator:/userdata# ./fscryptctl key_status a290ce05e9566ad81acda348a2b906ab /log Incompletely removed
# 读取文件内容 root@emulator:/userdata# cat /log/enc/message cat: can't open '/log/enc/message': Required key not available
# 查看目录内容 root@emulator:/userdata# ls /log/enc message testdir
# 创建新目录 root@emulator:/userdata# mkdir /log/enc/test mkdir: can't create directory '/log/enc/test': Required key not available |
2. 提取块设备重新挂载,测试加密效果
# 提取log分区 root@emulator:/userdata# dd if=/dev/mmcblk0p36 of=/ota/logdev 8388608+0 records in 8388608+0 records out
# ubuntu上重新挂载 dev@dev-bluesky:~/sambashare$ sudo mount logdev log [sudo] password for dev: dev@dev-bluesky:~/sambashare$ cd log dev@dev-bluesky:~/sambashare/log$ cd enc
# 文件名、目录名均为密文状态 dev@dev-bluesky:~/sambashare/log/enc$ ls qTheaAXRLsb6DbHDVfXjgFj64qvDXbBehm6d9DQjFNb1DYQdtfUG0B wqQqMnICWHOGFmyU1jnUkYWvNQgh2xp98yKUBmdu1D,mRECmxlMqAD
# 无法查看文件内容 dev@dev-bluesky:~/sambashare/log/enc$ cat qTheaAXRLsb6DbHDVfXjgFj64qvDXbBehm6d9DQjFNb1DYQdtfUG0B cat: qTheaAXRLsb6DbHDVfXjgFj64qvDXbBehm6d9DQjFNb1DYQdtfUG0B: Required key not available dev@dev-lixiang:~/sambashare/log/enc$ ls wqQqMnICWHOGFmyU1jnUkYWvNQgh2xp98yKUBmdu1D,mRECmxlMqAD |