#加密密钥 #加密 #FUSE #安全 #文件加密 #FUSE 文件系统

nightly bin+lib rencfs

一个在 Linux 上使用 FUSE 挂载的加密文件系统。它可以用来创建加密目录。

48 个版本 (11 个破坏性更新)

0.13.66 2024 年 8 月 19 日
0.13.59 2024 年 7 月 31 日

133文件系统

Download history 562/week @ 2024-05-02 417/week @ 2024-05-09 937/week @ 2024-05-16 114/week @ 2024-05-23 144/week @ 2024-05-30 1473/week @ 2024-06-06 115/week @ 2024-06-13 224/week @ 2024-06-27 162/week @ 2024-07-04 6/week @ 2024-07-11 182/week @ 2024-07-25 93/week @ 2024-08-01 1/week @ 2024-08-08 383/week @ 2024-08-15

每月 660 次下载

MIT/Apache

400KB
10K SLoC

rencfs

rencfs-bin crates.io docs.rs clippy tests release codecov Matrix Discord Zulip Open Source Helpers

[!警告]
这个crate还没有被审计,它使用了众所周知且经过审计的ring crate,所以原则上至少原始应该提供类似的安全级别。
这仍在开发中。请勿使用它处理敏感数据,请等待稳定版发布。
它主要适用于实验性和学习项目。

一个用 Rust 编写的加密文件系统,在 Linux 上通过 FUSE 挂载。它可以用来创建加密目录。

然后您可以安全地将加密目录备份到不受信任的服务器,而不用担心数据泄露。您也可以将其存储在任何云存储中,如Google Drive、Dropbox等,并跨多个设备同步。

您可以使用它作为 CLI 或用它构建自定义的 FUSE 实现。

主要特性

  • 使用公认的经过审计的 AEAD 密码学原语进行安全
  • 数据完整性,数据写入WAL以确保即使在崩溃或断电的情况下也能保持完整性
  • 所有元数据和内容都进行了加密
  • 使用 mlock(2) 和零化安全地管理内存中的凭据
  • 基于密码生成加密密钥
  • 密码保存在操作系统的密钥链中
  • 更改密码而无需重新加密所有数据
  • 读写操作中快速查找
  • 并行写入
  • 通过 FUSE 暴露
  • 所有操作都是完全并发的

功能

  • 它将所有加密数据和管理加密密钥的元信息保存在一个专用目录中,该目录中的文件按inode结构(包括元信息),二进制内容的文件和包含文件/目录条目的目录。所有数据、元数据和文件名都进行了加密。对于新文件,它在u64空间中随机生成inode编号,因此在使用离线并稍后同步时减少了冲突的机会。
  • 密码从CLI收集并在应用程序运行时保存在操作系统密钥链中。这是出于安全原因,我们在不活动时从内存中清除密码,并在需要时再次从密钥链中重新加载它。
  • 主加密密钥也使用从密码派生的另一个密钥进行加密。这允许在不重新加密所有数据的情况下更改密码,我们只需重新加密主密钥。
  • 文件以256KB的块加密,因此在进行更改时,我们只需重新加密这些块。
  • 读写时快速定位,因此如果您正在观看电影,您可以跳转到任何位置,这将非常快速。这是因为我们可以定位到特定的块。
  • 加密密钥在空闲时在内存中进行zeroize。同时,它在使用时被mlock以防止移动到交换区。在不读取时,它也被mprotect

进行中

  • 通过将每次更改保存到WAL来确保文件完整性,因此,在崩溃或电源故障后重启时,我们将应用挂起的更改。这使得写操作原子化。
  • 对同一文件进行并行写入,非常适合类似BT的应用程序

堆栈

  • 它完全基于tokiofuse3异步构建
  • ring用于加密和argon2用于密钥派生函数(创建用于从密码加密主加密密钥的密钥)
  • rand_chacha用于随机生成器
  • secrecy用于在内存中安全地存储密码和加密密钥,并在不再使用时将其清零。它只在使用时将加密密钥保留在内存中,在不活跃时将释放并在内存中清零它们
  • blake3用于哈希
  • 使用keyring在OS密钥环中保存密码
  • tracing用于日志记录

用法

使用Docker进行快速尝试

获取镜像

docker pull xorio42/rencfs

启动一个容器以在其中设置挂载

docker run -it --device /dev/fuse --cap-add SYS_ADMIN --security-opt apparmor:unconfined xorio42/rencfs:latest /bin/sh

在容器中创建挂载和数据目录

mkdir fsmnt && mkdir fsdata

启动rencfs

rencfs mount --mount-point fsmnt --data-dir fsdata

输入加密密码。

获取容器ID

docker ps

在另一个终端中,使用上述ID附加到正在运行的容器

docker exec -it <ID> /bin/sh

从这里,您可以在fsmnt目录中创建文件来测试它

cd fsmnt
mkdir 1
ls
echo "test" > 1/test
cat 1/test

作为库

对于库,您可以查阅文档

命令行工具

依赖关系

要使用加密文件系统,您需要在您的系统上安装FUSE。您可以通过运行以下命令(或根据您的发行版)进行安装。

Arch

sudo pacman -Syu && sudo pacman -S fuse3

Ubuntu

sudo apt-get update && sudo apt-get -y install fuse3

从AUR安装

您可以使用以下命令安装加密文件系统的二进制文件

yay -Syu && yay -S rencfs

使用cargo安装

您可以使用以下命令安装加密文件系统的二进制文件

cargo install rencfs

以下是一个使用加密文件系统的基本示例

rencfs mount --mount-point MOUNT_POINT --data-dir DATA_DIR
  • MOUNT_POINT作为客户端,在给定路径挂载FUSE
  • DATA_DIR是存储加密数据的同步提供程序的位置。但它需要与data-dir位于同一文件系统上

它将提示您输入密码以加密/解密数据。

更改密码

主加密密钥存储在文件中,并使用从密码派生的密钥进行加密。这提供了更改密码而不需要重新加密整个数据的机会。这是通过使用旧密码解密主密钥,然后使用新密码重新加密它来完成的。

要更改密码,您可以运行以下命令

rencfs passwd --data-dir DATA_DIR 

DATA_DIR是加密数据存储的位置

它将提示您输入旧密码和新密码。

加密信息

您可以通过将此参数添加到命令行来指定加密算法。

--cipher CIPHER ...

其中,CIPHER 是加密算法。您可以使用 rencfs --help 命令来检查可用的加密。
默认值是 ChaCha20Poly1305

日志级别

您可以通过将 --log-level 参数添加到命令行来指定日志级别。可能的值有:TRACEDEBUGINFO(默认)、WARNERROR

rencfs --log-level LEVEL ...

在 Rust 中使用

更多信息请见这里

从源码构建

浏览器

Open in Gitpod

Open Rustlings On Codespaces

您可以在浏览器中编译、运行并快速尝试它。启动它后

sudo apt-get update && sudo apt-get install fuse3
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
mkdir mnt && mkdir data
cargo run --release -- mount -m mnt -d data

打开另一个终端

cd mnt
mkdir a && cd a
echo "test" > test.txt
cat test.txt

本地

目前,FUSEfuse3 包)仅在 Linux 上工作,因此要启动项目,您需要在 Linux 上。或者,您可以在容器中开发,这将启动一个本地 Linux 容器,IDE 将连接到它,您可以在其中构建和启动应用程序,并使用终端测试它。

获取源代码

git clone [email protected]:radumarias/rencfs.git && cd rencfs

依赖关系

Rust

要从源码构建,您需要安装 Rust,有关如何安装的详细信息,请参阅这里

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

因此,Rust 开发者通常会将此目录包含在其 PATH 环境变量中。在安装过程中,rustup 将尝试配置 PATH。由于平台、命令 shells 和 rustup 中的差异和错误,对 PATH 的修改可能需要重新启动控制台、注销用户或可能根本无法成功。

如果在安装后,在控制台中运行 rustc --version 失败,这很可能是最可能的原因。在这种情况下,请手动将其添加到 PATH 中。

项目配置为使用 nightly 工具链,在 rust-toolchain.toml 中,首次构建时将获取 nightly。

cargo install cargo-aur
cargo install cargo-generate-rpm

其他依赖项

此外,还需要以下依赖项(或根据您的发行版)

Arch

sudo pacman -Syu && sudo pacman -S fuse3 base-devel

Ubuntu

sudo apt-get update && sudo apt-get install fuse3 build-essential

Fedora

sudo dnf update && sudo dnf install fuse3 && dnf install @development-tools

调试构建

cargo build

发布构建

cargo build --release

运行

cargo run --release -- mount --mount-point MOUNT_POINT --data-dir DATA_DIR

开发设置

如果您不想被提示输入密码,可以设置此环境变量并按如下方式运行:

RENCFS_PASSWORD=PASS cargo run --release -- mount --mount-point MOUNT_POINT --data-dir DATA_DIR

对于开发模式,建议使用 DEBUG 日志级别运行。

cargo run --release -- --log-level DEBUG mount --mount-point MOUNT_POINT --data-dir DATA_DIR

为 Fedora 构建本地 RPM

这使用了 cargo-generate-rpm

cargo install cargo-generate-rpm
cargo build --release
cargo generate-rpm

生成的 RPM 将位于此处:target/generate-rpm

安装和运行本地 RPM

cd target/generate-rpm/
sudo dnf localinstall rencfs-xxx.x86_64.rpm

在容器中开发

请参阅如何为 RustRoverVsCode 配置。

您可以使用项目中的 .devcontainer 目录来启动一个容器,其中包含构建和运行应用程序所需的所有必要工具。

最低支持的 Rust 版本 (MSRV)

最低支持的版本是 1.75

未来

性能

Aes256Gcm平均比 ChaCha20Poly1305 快 1.28 倍。这是因为大多数 CPU 通过 AES-NI 对 AES 进行了硬件加速。但是,在没有硬件加速的地方,ChaCha20Poly1305 更快。此外,ChaChaPoly1305SIMD 方面表现更好。

加密比较

AES-GCM 与 ChaCha20-Poly1305

  • 如果你有硬件加速(例如 AES-NI),那么 AES-GCM 提供更好的性能。在我的基准测试中,它平均快了 1.28 倍。
    如果你没有硬件加速,AES-GCM 要么比 ChaCha20-Poly1305 慢,要么在缓存时间泄露你的加密密钥。
  • AES-GCM 可以针对多个安全级别(128-192-256-),而 ChaCha20-Poly1305 仅定义在 256- 安全级别。
  • nonce 的大小
    • AES-GCM:可变,但标准是 9612 字节)。如果你提供一个更长的 nonce,它将被哈希到 16 字节
    • ChaCha20-Poly1305:标准版本使用 96- nonce(12 字节),但原始版本使用 64- nonce(8 字节)。
  • 单个(密钥,nonce)对的磨损
    • AES-GCM:消息长度必须小于 2^322 块(即 2^3632 字节,也称为 2^39256),大约为 64GB。这也使得对具有长非ces的 AES-GCM 的安全分析变得复杂,因为散列的非ces不以 00 00 00 02 设置的最低 4 字节 开始。
    • ChaCha20-Poly1305:ChaCha 有一个内部计数器(在标准化 IETF 变体中为 32,在原始设计中为 64)。最大消息长度为 2^39 - 256,大约为 256GB
  • 这两种算法都不是 nonce误用抵抗的
  • ChaChaPoly1305SIMD 方面表现更好

结论

两者都是不错的选择。 AES-GCM硬件支持 的情况下可能更快,但 ChaCha20-Poly1305 的纯软件实现几乎总是 快速常量时间

安全

  • 幽灵读取:从文件中读取旧内容,这是不可能的。数据使用 WAL 写入,并定期刷新到文件。这确保了数据完整性和更改顺序。可能出现的一个问题是,如果我们执行截断操作,我们改变了文件的内容,但在我们用新的文件大小写入元数据之前进程被杀死了。在这种情况下,下次我们挂载系统时,我们仍然看到旧的文件大小。然而,文件的内容可能更大,我们读取到旧大小偏移量,因此我们不会拾取截断时增加大小所写入的新零字节。如果内容更小,读取会停止并结束实际内容的文件结束,所以这不会是一个大问题
  • 会泄露什么样的元数据:几乎没有。文件名、实际文件大小和其他文件属性(时间、权限、其他标志)都保持加密。它可能泄露以下内容
    • 如果一个目录有子目录,我们将这些子目录保存在一个以inode编号为名的目录中,子目录的加密名称作为文件存储在其中。因此,我们可以看到目录有多少个子目录。然而,我们不能识别实际的目录名,我们只能看到它的inode编号(每个文件的内部表示,类似于id),我们也不能看到目录或子目录的实际文件名。此外,我们也不能确定哪个文件内容对应于目录的子目录
    • 每个文件内容都保存在单独的文件中,因此我们可以看到加密内容的尺寸,但不是实际文件大小
    • 我们还可以看到文件最后被访问的时间
  • 始终建议至少为敏感数据使用加密磁盘,本项目不是替代品
  • 为了降低加密密钥从内存中被暴露的风险,建议在操作系统级别禁用内存转储。请参阅这里了解如何在Linux上操作
  • 冷启动攻击:为了降低这种攻击的风险,我们将加密密钥保留在内存中,仅在我们真正需要它来加密/解密数据时,并在之后将其置零。我们还在一段时间的非活动期后将其从内存中删除
  • 请注意,该项目尚未由任何安全专家审计。该项目以安全为前提,并尝试遵循所有最佳实践,但无法保证其安全性
  • 此外,请备份您的数据,该项目仍在开发中,可能存在导致数据丢失的错误

注意事项

  • 请注意,该项目并不试图重新发明轮子或优于已经证实的实现
  • 该项目不想在任何方面替代已经证实的文件加密解决方案。如果您真的需要一个几乎无懈可击的解决方案,那么这可能不是最适合您的。但它试图提供一个简单的加密解决方案,在考虑上述所有安全问题时应该使用
  • 它始于Rust编程语言的学习项目,我感到继续构建下去很有意义
  • 这是一个相当简单且标准化的实现,试图尊重所有安全标准,正确使用安全和健壮的原始程序,以便可以在此基础上扩展。确实,它还没有达到可以“对抗”其他知名实现的成熟度。但它可以是一个供他人学习或在此基础上构建的项目,或者为什么不为一些人实际使用它并考虑到上述所有因素

贡献

请随意将其分叉,以任何您希望的方式更改和使用它。如果您构建了有趣的东西并愿意分享,则拉取请求总是受欢迎的。

如何贡献

请参阅CONTRIBUTING.md

依赖关系

~23–38MB
~699K SLoC