2

一个无感知的网盘加密实现方式探索

 2 years ago
source link: https://www.ihcblog.com/OneEncrypt/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一个无感知的网盘加密实现方式探索

发表于

2019-08-06 更新于 2022-02-27

本文讲介绍一种无感知的网盘加密方式(以 OneDrive 为例),并在项目基本完工后开源代码

做个东西起因是最近弄到了一个 5TB 的 OneDrive 账号,感觉拿来做备份挺好的。试了下 OneDrive for Business 国内似乎会连香港的节点,上海联通上传大概是 10M 的带宽。但是说到个人数据就不得不谈隐私问题,我的数据会被别人获取到吗?

一番 Google 后发现,无论是 OneDrive 还是 GDrive,只要是域下的账号,管理员就有权限查看个人文件。虽然我的账号是自己的域下的,我仍旧对于把数据明文交给微软不那么放心。

目前有几种网盘加密的解决方案:Boxcryptor、Cryptomator、Duplicati 等。归纳一下大概有这么几种实现方式:

  1. 最蠢的实现:数据保留两份,一份加密版一份解密版,加密版直接丢 OneDrive 的同步文件夹下。
  2. 稍微好一些的实现:数据只保留加密版,同时启动另一个软件用于即时解密。该软件会让用户选择一个文件夹(Cryptomator),或创建一个虚拟驱动器(Boxcryptor),在使用时直接使用该目录即可拿到明文文件。

在我看来这两种实现都不那么聪明。因为我的需求只是对 OneDrive 或 GDrive 加密,本地应该存储明文,否则大量 IO 时会造成性能瓶颈。毕竟网盘的 IO 是绝对小于本地 IO 的,甚至远小于我的上传带宽。同时软件出错会直接影响我的数据安全,我也是很慌的。

我尝试做了一个无感知的网盘加密器,暂时起名叫 OneEncrypt 吧。它只包含一个可执行文件和一个动态链接库文件。

基本原理是通过映像劫持来启动我的可执行文件,该可执行文件其实只是一个启动器,负责启动 OneDrive(以调试模式避开 IFEO 并暂停执行),注入动态链接库文件。当动态链接库被加载后会尝试以 IAT Hook 的形式注入 IO 相关的系统调用。之后继续运行原程序,启动器退出。

在 OneDrive 正常运行过程中没有额外进程运行,同时 Hook 也只对 OneDrive 进程生效。这样在其 ReadFile 时可以额外做一下加密,在 WriteFile 时做解密。

对比其他的加密解决方案,这种方式有明显的好处:

  1. 性能好。这一点之前提到了,不再赘述。
  2. 兼容性好。本地程序直接读写非加密文件,而不是读写我的虚拟文件系统。例如在 Boxcryptor 中存放的 VHD 文件无法正常 Mount。
  3. 数据安全不依赖加密软件本身。加密软件出错或 key 丢失并不会影响本机数据。
  4. 用户零感知,无进程,并且无需改动 OneDrive 可执行文件本身,可以随意更新。
  5. 还可以做一些额外的 Tweak,比如 OneDrive 不支持同步软链接,那么可以在 Hook 中修改 API 的返回结果。

对于加密算法,需求是支持随机读取和高性能,比如 AES-CTRxchacha20。以 xchacha20 为例,加密过程中会获取该文件对应的 nonce ,对于文件的每个块,都会有一个顺序的 blockId,该 id 会用于块加密,块与块之间是独立的,所以当块大小设置成较小值时,可以认为是满足随机读写要求的。

参考 Boxcryptor 的实现,这里并没有将 nonce 放在文件开头,而是另外存在了 key.storage 的特殊文件中。这么做主要是为了避免麻烦。可能后续还需要改动。

目前的进度是基于 Detourslibsodium 库,完成了启动器和基本的 ReadFileWriteFile Hook,可以通过简单的 POC 测试;但是对于 ReadFileEx, SetFilePointer 等还没有充足的支持。

基本开发完成后会开源于 https://github.com/ihciah/OneEncrypt


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK