安全问题

客户端与服务器之间的连接是如何加密的?
自 4.1.0 版本起,Seafile 使用 HTTP (S) 在客户端和服务器之间同步文件。
加密资料库
Seafile 提供了“加密资料库”功能来保护隐私。文件的加密/解密在桌面客户端进行,密码不会存储在服务器上。即使是系统管理员,也无法查看加密资料库的文件内容。
该功能有一些限制:
  1. 文件元数据不会被加密。元数据包括:完整的目录和文件名列表、每个文件的大小、编辑历史、时间,以及修改过的字节范围。
  2. 客户端加密目前在网页浏览器和桌面客户端的云文件浏览器中不起作用。当通过网页或云文件浏览器访问加密资料库时,需要输入密码,服务器会使用该密码解密资料库的“文件密钥”,并在内存中缓存一小时。明文密码从不会在服务器端存储或缓存。
  3. 如果通过网页界面创建加密资料库,密码和加密密钥会经过服务器。如果需要端到端加密,必须通过桌面客户端创建加密资料库。
  4. 在加密协议版本 4 中,每个资料库使用自己的 salt 来生成 key/iv 对。但同一资料库内的所有文件共享相同的 salt 和 key/iv 对。协议版本 2 中,所有资料库共享同一个固定 salt,但有独立的 key/iv 对。
  5. 加密资料库不保证文件完整性。例如,服务器管理员仍然可以修改文件内容,客户端无法检测出这种篡改。
iOS 客户端自 2.1.6 版本起支持客户端加密;Android 客户端自 2.1.0 版本起支持。但从 3.0.0 版本开始,iOS 和 Android 客户端取消了客户端加密,必须将密码传输到服务器来完成加解密。
加密资料库的工作原理
创建加密资料库时,需要为其设置密码。该资料库中的所有数据都会在上传到服务器前使用该密码加密。
加密/解密过程:
目前支持两种加密协议版本:版本 2 和版本 4。二者的基本流程一致:
  1. 生成一个 32 字节的强随机数,用作文件加密密钥(file key)。
  2. 使用用户提供的密码加密该文件密钥。首先通过安全哈希算法从密码派生出 key/iv 对,再用 AES 256/CBC 加密文件密钥,得到“加密文件密钥”。该加密文件密钥会存储在服务器上。
  3. 从密码和资料库 ID 中派生出一个“magic token”,用于在解密前验证密码。
  4. 所有文件数据通过文件密钥和 AES 256/CBC 加密。文件密钥再经 PBKDF2-SHA256(迭代 1000 次)生成 key/iv 对。加密后的数据上传到服务器。
版本 2 和版本 4 的区别在于 salt 的使用:版本 2 使用固定 salt,版本 4 为每个资料库生成独立的随机 salt。
密码验证的安全哈希算法:
安全哈希算法用于从密码派生 key/iv 对,因此选择计算代价高的算法能有效防止暴力破解。
  • 在 12 版之前,Seafile 使用固定算法 PBKDF2-SHA256(1000 次迭代),安全性已不足。
  • 从 12 版开始,管理员可选择不同的哈希算法:
  1. PBKDF2:唯一参数是迭代次数。需随着硬件计算力的提升逐步增加迭代次数。默认是 1000,2023 年建议为 600,000。
  2. Argon2id:对 GPU 也有高计算成本。参数包括时间成本、内存成本、并行度,例如 "2,102400,8"。这是 Seafile 默认使用的参数。详见 https://github.com/P-H-C/phc-winner-argon2
客户端加解密
上述加密流程可在桌面端和移动客户端执行。Seahub 浏览器客户端则在服务器端完成加解密,因此密码需要传输到服务器。
当将加密资料库同步到桌面客户端时,客户端需验证密码。创建资料库时,会根据密码和资料库 ID 生成 magic token,该 token 存储在服务器上,客户端使用它来检查密码是否正确。
出于安全考虑,明文密码不会存储在客户端。客户端只保存由文件密钥派生的 key/iv 对。如果忘记密码,将无法恢复或访问服务器上的数据。
为什么 fileserver 能让知道未分享私有文件 URL 的人获取文件内容?
当用户点击文件下载链接时,系统会生成一个随机 URL,仅能访问一次,之后即失效。因此即便其他人知道该 URL,也无法再次访问。
在 Seafile 12 版中,该机制已改变。文件下载使用类似 https://yourserver.com/seafhttp/repos/{library id}/file_path 的 URL,服务器通过 Cookie 或 API token 进行授权验证。这种方式更利于缓存,同时保持安全。
Seafile 如何存储用户登录密码?
用户登录密码仅以哈希形式存储。需要注意,登录密码与加密资料库的密码不同。数据库中的格式为:
            
                
                
PBKDF2SHA256$iterations$salt$hash
分为四部分:
  • 使用的哈希算法(当前为 PBKDF2-SHA256,可切换为更强算法);
  • 迭代次数;
  • 随机生成的 salt;
  • 最终生成的密码哈希值。
哈希计算方法:
  • 生成 32 字节的强随机数,作为 salt;
  • 使用 PBKDF2(password, salt, iterations) 计算哈希,目前迭代次数为 10000。