把文件夹压缩成带密码的ZIP,发给别人。然后不用密码打开这个压缩包——你会看到一份清单:Passport.jpg,2.4 MB,2026-08-14;Contract_signed.pdf,180 KB,2026-08-12;Bank_statement_July.pdf,95 KB,2026-08-01。 文件内容确实被加密了,一个字节都读不出来。但这份文件清单,就明晃晃地摆在明文里。 这不是某个工具的bug,是ZIP格式本身的设计。在ZIP归档里,加密只覆盖条目数据;中央目录——文件名、大小、时间戳、条目数量——始终保持可读,因为工具正是靠它来列出压缩包内容,而不必先解密。 对软件分发来说,这个设计完全合理。对隐私来说,它是个洞。因为很多时候,文件名本身就是秘密。没人需要打开Passport.jpg才知道你有些什么,一份Divorce_settlement_final.pdf,光看目录列表就把整个故事讲完了。 7-Zip自家的.7z格式有"加密文件名"选项,标准ZIP没有。而标准ZIP恰恰是每台手机、每台电脑不装任何软件就能打开的格式。 **两层压缩,把名字藏起来** 既然ZIP的中央目录无法加密,那就别往里放任何有意义的东西。做法是两层:先把文件夹压成一个内层归档,普通压缩、不加密;再把这一个文件压成外层归档,加密。这样外层目录里只列出一个条目,名字什么信息都不透露——没有文件名,没有大小,没有日期,连里面装了几样东西都看不出来。 内层归档保留真实名字,没有密钥就看不见,恢复时在解密之后读取。外面藏住名字,里面一点不损失。 **加密方式只有一种选择** 可用的加密方法有三种:STANDARD、AES_128、AES_256。STANDARD是遗留的ZipCrypto,绝不该拿去上线。它会被已知明文攻击破解——攻击者只要知道或猜到里面的一部分内容,就能还原密钥。 对一个装满照片的应用来说,这等于白送攻击者一份已知明文:JPEG的文件头是固定的。它不是弱加密,是一道画了把锁的减速带。 两层都用NO_COMPRESSION,这不是偷懒。照片和视频本身已经压缩过,对JPEG跑deflate几乎没有任何收益,却要付出真实的CPU时间,而且现在要做两遍。一个1 GB的文件夹,换来的是手机上几分钟的发烫,省下的体积要用KB来量。关掉压缩后,整个操作退化成复制加加密,归档体积约等于文件夹体积——当目标是保存文件而不是缩小文件时,这正是想要的结果。 **真正会压垮流程的数字:峰值磁盘占用** 两层意味着同时存在两份拷贝。在一台几乎装满的手机上——而拍照片多的人,手机大多如此——这就是成功和跑到80%失败的区别。 批量导出时,最朴素的峰值是文件夹体积的三倍:暂存拷贝、内层归档、外层归档。在内层吞掉暂存拷贝的那一刻就把它删掉,峰值能压回两倍。开始之前先检查可用空间,并且用真实的倍数,别用那个好看的倍数。一次900 MB的导出中途失败,留下的是一个损坏的文件,和一个不再信任你的用户。 **密钥:20个字符,100比特熵** 密钥从32个符号的字母表里取20个字符,100比特熵。这个字母表有两个刻意的性质。 第一,没有易混字符:没有0,没有1,没有I,没有O。这把密钥会被人在电话里念出来,从一台设备敲到另一台,从截图上眯着眼辨认。一个会被看错的字符,是一个穿着排版外衣的安全问题——因为用户不会得出"我打错了"的结论,他们会得出"你的应用坏了"。 第二,正好32个符号,所以用31做按位与,就能把随机字节无偏地映射到一个符号上。换成别的字母表大小就需要取模,而对非2的幂取模会让分布向字母表前部倾斜。这个偏差很小,但避免它完全免费。 外层归档还可以起一个中性的名字,比如ToFolder-2026-08-20.zip,因为它在聊天软件里出现时,还没等人打开就已经暴露了。只是恢复流程原本从归档文件名推导文件夹名,中性名字会恢复出一个叫"ToFolder-2026-08-20"的文件夹,比没用还糟。两层结构顺手解决了这个问题:内层归档保留真实名字,解密后读取。

打开网易新闻 查看精彩图片