HideFile 在浏览器里,用由你的密码生成的密钥加密文件,再把加密后的结果存放在一张普通的照片、PDF 或视频里。你的文件和密码都不会发送给我们。本页写明了所用的算法和参数,列出应用到底会发送什么,并坦率说明它的局限,包括细心的读者会拿来质疑我们的那些。
记住两个概念,后面就不会混。加密是安全层:没有密码,内容无法读取。封面文件是伪装:它改变的是加密后的字节在别人浏览你的文件时的样子,并不会让它们对正在检查的人变得不可见。
你的密码在你的设备上变成密钥
创建上锁文件时,HideFile 用 Argon2id(1.3 版)把你的密码变成密钥。这是一种内存困难型(memory-hard)的密钥派生函数。内存困难的意思是,每次尝试除了花时间,还要占用一块内存,所以即使用专门为猜密码打造的硬件,猜测也依然很慢。
成本取决于文件是在哪里创建的。在桌面浏览器中,Argon2id 使用 64 MiB 内存、3 次迭代、单线程通道。如果浏览器报告自己是手机或平板,或内存不超过 4 GB,则使用 19 MiB、2 次迭代、单线程通道,因为手机浏览器无法稳定地在每次解锁时占用 64 MiB 而不出错。这个较低的设置符合 OWASP 对 Argon2id 的最低推荐。这些参数存放在上锁文件内部,所以在桌面上创建的文件,在手机上打开时仍保持 64 MiB 的成本。
每个上锁文件都有一个随机的 16 字节盐值,和文件存放在一起。两个人选了同样的密码,最终得到的密钥也不同,所以没有人能预先算好一张猜测表,拿去对付所有文件。
你的文件用 XChaCha20-Poly1305 封存
由密码生成的密钥并不直接加密你的文件。每个上锁文件都有自己的随机 256 位文件密钥,在你的设备上生成。密码密钥负责包裹这个文件密钥,文件密钥负责封存你的文件。
封存使用 XChaCha20-Poly1305,这是一种带认证的密码算法:既保证内容私密,也能发现篡改。文件以记录的形式存放,每条记录都有自己的随机 192 位 nonce 和一个 Poly1305 认证标签。如果某条记录被改动,不论是副本损坏还是有人故意改的,解锁都会报错失败,而不是悄悄返回错误的内容。
这两种算法都来自开源的 RustCrypto 库(argon2 和 chacha20poly1305 这两个 crate)。我们自己用 Rust 写的核心使用它们,并编译成 WebAssembly 在你的浏览器中运行。HideFile 运行的每个地方用的都是同一个核心,所以要检查的只有一份实现,而不是每个平台一份。

你锁定的任何东西都不会上传
锁定、解锁和保存都在浏览器标签页里完成。你的文件、文件名、密码和密钥都不会发送到 HideFile 的服务器,而且也没有任何存放上锁文件的 HideFile 服务器。唯一的例外是你自己开启的功能:如果你连接了自己的 S3 兼容存储桶,比如 Cloudflare R2,应用会把加密后的字节从你的设备直接发到那个存储桶,而不是发给我们。
应用确实会在你设备的浏览器中保存一些东西。为了让重新打开更快,它会保存你最近打开的那个上锁文件的一份副本(仍是加密的),最长一天、最大 100 MB。你保存下来以便重复使用的文件,以及打开中的文件的工作副本,存放在浏览器的私有文件存储里。它还会记住主题和视图之类的设置,以及你最近打开的十个封面的名称、大小和时间,但绝不会记住密码。清除网站数据会把这些全部删除。在共用或借来的电脑上,用完请这样做。
我们发送的分析数据不含任何文件数据
我们用 PostHog 统计使用情况,并且关闭了自动捕获,所以点按操作和页面内容都不会被记录。发送的内容有:
- 页面浏览:页面路径和来源网址、你的浏览器和设备类型,以及屏幕尺寸。
- 大致的国家或地区,由 PostHog 在请求到达时根据你的 IP 地址推算。
- 保存在你浏览器里的一个匿名随机标识符,用于统计重复访问。
- 三个事件:
locked_file_created、locked_file_opened和locked_file_saved,每个只带封面类型(png、jpeg、mp4 或 pdf)和平台(web 或 native)。
文件名、大小、数量、路径、密码、密钥、内容和错误信息都不会发送。像 uBlock Origin 这样的内容拦截器会拦截这些分析,应用的使用不受影响。你可以自己验证:打开浏览器的开发者工具,在锁定和保存文件时观察“网络”(Network)标签,看有没有任何请求带着你的文件。隐私政策才是这份清单具有约束力的版本。
威胁模型:按“谁”来说明
| 谁 | 结果 | 原因 |
|---|---|---|
| 翻看你的手机、笔记本电脑或云盘的人 | 能挡住 | 他们看到的是一张普通的照片、PDF 或视频,没有任何名字像保险箱的东西 |
| 知道你手机锁屏密码的人 | 能挡住 | 封面有自己的密码,与设备锁无关 |
| 拿到封面副本但没有密码的人 | 能挡住 | 内容保持加密 |
| 取证检查人员,或者知道 HideFile 并仔细检查的人 | 藏不住 | 他们能看出被加了数据;内容仍是加密的 |
| 能强迫你交出密码的人 | 挡不住 | 没有任何软件能解决这个问题 |
| 恶意软件、屏幕录制,或在已解锁设备旁边的窥视者 | 挡不住 | 文件打开期间,他们看到的就是你看到的 |
取证工具能看出被加了数据
HideFile 并不试图向取证检查隐瞒数据的存在,也没有这样声称。你的加密记录位于封面自己的文件结构之中,普通查看器会忽略它们。专门的工具,或者知道该找什么的检查人员,能识别出被加入了记录。文件大小是更简单的破绽:一张简短的度假快照带着几个 GB 就不寻常,把封面和没动过的原图一比就立刻看出差别。
检查人员得到的是“这里有东西”这个事实,而不是内容。没有密码,这些记录依然是封存的。这就是诚实的边界:“藏在眼皮底下”应对的是好奇的人和普通的搜查,而不是拿着你设备、决心已定的检查人员。边境检查、训练有素的检查人员或法律压力,它都不合适。
防篡改覆盖的是封存的记录,而不是封面的每一个字节。重新保存、去除元数据或重新压缩封面的 App,可以在加密毫无警报的情况下改动图片本身,还可能把记录整个去掉,这会毁掉里面的文件。请把封面当作文件保存。
密码无法找回
我们不持有你的密码,也无法从上锁文件里推出它。没有重置链接,没有恢复码,也没有任何客服流程能打开文件。密码丢了,里面的文件就丢了。这是设计本身的特性,也是持有你封面副本的人不能直接找我们来打开的原因。
哪些不是开源的,也没有经过审计
HideFile 的源代码没有公开,也没有独立机构审计过。算法是标准的,实现它们的库是开源的,本页和应用内的安全页面给出了参数,但我们调用它们的代码,目前外人还读不到。
这很重要。有位 Hacker News 评论者在回应另一个把数据藏进照片的闭源工具时,用四个词概括了这一点:“no source code == no security.”(没有源代码就没有安全。)社区里还有人指出,网页应用每次访问都会从服务器重新下发,所以即使公开了源代码,也需要有办法确认你运行的代码与它一致。这两点都有道理,对按这个标准要求的读者来说,HideFile 目前还没有达到。我们宁愿直说,也不争辩。如果你发现了漏洞,请发邮件到 support@hidefile.app,附上复现步骤,并在公开之前给我们合理的时间发布修复。
资料来源
- HideFile:How HideFile protects you
- HideFile:Privacy Policy
- OWASP:Password Storage Cheat Sheet
- RFC 9106:Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications
- RustCrypto:argon2 crate 和 chacha20poly1305 crate
- Hacker News:Show HN: a hardware-bound local password vault hidden in a photo,评论 49509561
- Hacker News:comment on browser delivery of encrypted apps