乐趣区

关于算法:龙蜥白皮书精选基于-SM4-算法的文件加密fscrypt实践

文 / 张天佳

通常咱们会以文件作为数据载体,应用磁盘,USB 闪存,SD 卡等存储介质进行数据存储,即使数据曾经离线存储,依然不能保障该存储介质不会失落,如果失落那么对于咱们来说有可能是灾难性的事件。因而对这些离线存储的重要数据文件进行加密是十分有必要的,本节将介绍如何应用国密算法加密文件系统中的文件。

01 fscrypt 简介

内核中的 fscrypt 是一个库,文件系统能够应用它以反对文件和目录的通明加密。

与 dm-crypt 不同,fscrypt 在文件系统级别而不是块设施级别运行。这容许它应用不同的密钥加密不同的文件,并在同一文件系统上领有未加密的文件。这对于多用户零碎十分有用,在该零碎中,每个用户的静态数据都须要与其余用户进行加密隔离。除了文件名,fscrypt 不加密文件系统的元数据。

与作为栈式文件系统的 eCryptfs 不同,fscrypt 是间接集成到反对的文件系统中,目前反对 fscrypt 的文件系统是 ext4、F2FS 和 UBIFS。fscrypt 容许读取和写入加密文件,而无需在页面缓存中同时缓存解密和加密页面,从而将应用的内存简直减半并使其与未加密文件保持一致。同样,须要一半的 dentry 和 inode。eCryptfs 还将加密文件名限度为 143 字节,从而导致应用程序兼容性问题;fscrypt 容许残缺的 255 个字节 (NAME_MAX) 长度的文件名。最初,与 eCryptfs 不同,fscrypt API 能够由非特权用户应用,而无需依赖其它任何组件。

fscrypt 不反对就地加密文件。相同,它反对将空目录标记为已加密。而后,在用户空间提供密钥后,在该目录树中创立的所有惯例文件、目录和符号链接都将被通明地加密。

02 反对的加密模式和用法

fscrypt 容许为文件内容指定一种加密模式,为文件名指定一种加密模式。不同的目录树容许应用不同的加密形式。目前反对以下几种加密形式对:

  • AES-256-XTS 算法用于加密内容,AES-256-CTS-CBC 算法用于加密文件名
  • AES-128-CBC 算法用于加密内容,AES-128-CTS-CBC 算法用于加密文件名
  • Adiantum 算法同时用于加密文件内容和文件名
  • AES-256-XTS 算法用于加密内容,AES-256-HCTR2 算法用于加密文件名(仅限 v2 策略)
  • SM4-XTS 算法用于加密内容,SM4-CTS-CBC 算法用于加密文件名(仅限 v2 策略)

AES-128-CBC 仅为具备不反对 XTS 模式的加速器的低功耗嵌入式设施应用。要应用 AES-128-CBC,必须启用 CONFIG_CRYPTO_ESSIV 和 CONFIG_CRYPTO_SHA256(或其余 SHA-256 实现)以便应用 ESSIV。

Adiantum 是一种基于流明码的模式,即便在没有专用加密指令的 CPU 上也很快。与 XTS 不同,它也是真正的宽块模式。要应用 Adiantum,必须启用 CONFIG_CRYPTO_ADIANTUM。此外,应启用 ChaCha 和 NHPoly1305 的疾速实现,例如 ARM 架构上的 CONFIG_CRYPTO_CHACHA20_NEON 和 CONFIG_CRYPTO_NHPOLY1305_NEON。

AES-256-HCTR2 是另一种真正的宽块加密模式,旨在用于具备专用加密指令的 CPU。AES-256-HCTR2 具备明文中的位翻转会更改整个密文的属性。因为初始化向量在目录中重复使用,因而此属性使其成为文件名加密的现实抉择。要应用 AES-256-HCTR2,必须启用 CONFIG_CRYPTO_HCTR2。此外,应启用 XCTR 和 POLYVAL 的疾速实现,例如 用于 ARM64 的 CRYPTO_POLYVAL_ARM64_CE 和 CRYPTO_AES_ARM64_CE_BLK。

最初是 SM4 算法,目前仅在 fscrypt v2 策略中启用。

03 应用 SM4 算法加密文件

🟢 筹备工作

fscrypt 依赖内核配置 CONFIG_FS_ENCRYPTION=y,这里操作系统抉择应用 ANCK 5.10 内核的 Anolis OS,其次,须要反对 fscrypt 个性的文件系统,这里以 ext4 为例,当然,F2FS 或者 UBIFS 也能够。

用户空间是通过 fscrypt API 跟内核实现交互的,对于用户来说,个别是通过 fscryptctl 或者 fscrypt 工具来下达加密策略。

本节内容以 fscryptctl(https://github.com/google/fscryptctl)工具为例来演示,目前这是一个第三方工具,须要手工装置,按如下惯例流程装置:

git clone https://github.com/google/fscryptctl.git

cd fscryptctl

make

make install

其次,抉择一块未用到的磁盘格式化为反对 fscrypt 的文件系统 ext4,并挂载。

mkfs.ext4 -O encrypt /dev/vda3

mount /dev/vda3 /mnt

🟢 通明加密文件

fscrypt 所用的加解密钥是关联在超级块上的,运行时是跟挂载点相关联的,增加删除密钥都是针对挂载点的操作,以下对密钥操作的命令都会带上挂载点。

按如下命令所示设置加密策略:

# 生成密钥文件,理论环境中利用应用更简单的密钥
> echo '1234567812345678' > /tmp/keyfile

# 增加该密钥到文件系统,返回密钥 ID,之后对密钥的操作都应用这个 ID 来索引
> fscryptctl add_key /mnt < /tmp/keyfile
23086a13ed81fd75ca5fe9b8f2ff25c7

# 查看密钥状态(不是必须)> fscryptctl key_status 23086a13ed81fd75ca5fe9b8f2ff25c7 /mnt
Present (user_count=1, added_by_self)

# 创立加密目录 endir,并设置加密策略
# 应用之前增加的密钥和 SM4 算法来加密该目录中的文件和子目录
> mkdir /mnt/endir
> fscryptctl set_policy --contents=SM4-XTS \
        --filenames=SM4-CTS 23086a13ed81fd75ca5fe9b8f2ff25c7 /mnt/endir

# 查看策略是否失效(不是必须)> fscryptctl get_policy /mnt/endir
Encryption policy for /mnt/endir:
    Policy version: 2
    Master key identifier: 23086a13ed81fd75ca5fe9b8f2ff25c7
    Contents encryption mode: SM4-XTS
    Filenames encryption mode: SM4-CTS
    Flags: PAD_32

此时,endir 曾经是反对通明加解密的一个目录,能够像失常目录一样创立删除文件,在该目录下进行一些惯例的文件操作,能够看到与一般目录没有区别:

> mkdir /mnt/endir/foo
> echo 'hello' > /mnt/endir/foo/hello

> cp -v /usr/include/curl/* endir
> tree /mnt/endir
/mnt/endir
├── curl.h
├── easy.h
├── foo
│   └── hello
└── websockets.h

🟢 锁定加密目录

之所以能像一般目录一样操作,是因为密钥曾经被增加到了文件系统中。接下来删除密钥后,就能看到目录被锁定,外面的所有门路和内容都是加密状态:

# 移除密钥
> fscryptctl remove_key 23086a13ed81fd75ca5fe9b8f2ff25c7 /mnt

> fscryptctl key_status 23086a13ed81fd75ca5fe9b8f2ff25c7 /mnt
Absent

# 处于加密状态的目录树
> tree /mnt/endir
/mnt/endir
├── 1H2e0BbS4MGZKAKEu6NVXniaYMWIrWDwbyzX6EVEWEN8tfWcWNgDyw
├── LvYw6Jl0a1jImKKOFPjtpG3hEDxjjuM6YIYqcMeXaWdzKUdaX0YCNQ
├── QBBz8_qGE4MJY6YVzfqVUkr6YeCSqtoQmbvG04BsR0lAr2oLwO0b2g
│   └── wOYdFlMRACjeBa-eSo3LuO4sE55q1YuFv-S_lVU-n498jdMjAt06JA
└── zoiobWxVG2DLjg8uMXfsVP11159zqQUjozJ8gmt1zyjayJlZ4awOhA

# 目录被锁定,无奈进行惯例文件操作,即使拔盘,也不能失去明文内容
> cat /mnt/endir/1H2e0BbS4MGZKAKEu6NVXniaYMWIrWDwbyzX6EVEWEN8tfWcWNgDyw
cat: /mnt/endir/1H2e0BbS4MGZKAKEu6NVXniaYMWIrWDwbyzX6EVEWEN8tfWcWNgDyw: Required key not available
> mkdir /mnt/endir/hello
mkdir: cannot create directory‘/mnt/endir/hello’: Required key not available

🟢 再次解锁加密目录

要解锁目录也很简略,从新增加密钥即可,文件系统会搜寻到正确的密钥并解锁相应目录:

> fscryptctl add_key /mnt < /tmp/keyfile
23086a13ed81fd75ca5fe9b8f2ff25c7

# 增加密钥后文件内容可失常拜访
> cat /mnt/endir/foo/hello
hello

04 后记

fscryptctl 是一个绝对原生的工具,更靠近内核,能够看到,该工具命令比较复杂,应用中须要记住很长一串密钥 ID,用户体验并不好。

理论环境中,个别会应用 fscrypt 工具来实现加密策略操作,该工具由 Google 开发,用 Go 语言写成,通过在用户层面保护了一些元数据来简化用户操作,命令更易于了解,也更靠近用户。

商密软件栈 SIG 主页:https://openanolis.cn/sig/crypto

附:商用明码技术最佳实际白皮书 https://openanolis.cn/shangmi

—— 完 ——

退出移动版