Apeleg Limited 在技术社区发布了开源前端加密工具 @apeleghq/cms-ep-sfx(版本号 v1.1.16,commit add3a36),让使用者在断网的气隙(Air-gapped)环境里,直接用浏览器把任意文件封装成一个单文件的自解密 HTML 网页。不用装解压软件,双击网页、输入口令即可还原文件。

二十年前,WinRAR 和 7-Zip 用 .exe 自解压归档解决了接收方没有装解压软件的痛点;今天,可执行二进制文件早已被各路安全软件围追堵截。Apeleg 的思路是借壳复活:把解密代码和密文统统塞进 HTML,现代浏览器普及的 Web Crypto API(SubtleCrypto)成了现成的运行引擎。但真正的分水岭不在于前端界面,而在于它打破了同类小工具自造黑盒协议的习惯,用工业级标准做了一次硬核对齐。

双层信封:从前端玩具跨入工业标准

以往做纯前端自解密网页的开源项目并不罕见,从 Portable Secret 到 htmlvault,大都习惯把加密数据塞进自定义的 JSON 结构。这种做法写起来省事,但一旦网页代码损坏或原项目停更,密文就变成了谁也无法解析的数字死账。

ts-cms-ep-sfx 采用的是严格的信封加密设计。系统先通过 PBKDF2-HMAC-SHA-512、32 字节随机盐及可配置迭代次数派生出 256 位 AES-CBC 密钥加密密钥(KEK),再按照 RFC 3211 PWRI 规范包裹随机生成的 256 位 AES-GCM 内容加密密钥(CEK)。实际的文件载荷则使用 AES-256-GCM 结合 12 字节新鲜 nonce 与 16 字节认证标签完成加密,整体数据结构遵循 RFC 5652 封装为标准的 CMS Authenticated EnvelopedData 格式。

双层信封加密机制(RFC 3211 与 RFC 5652) 1. 密钥派生 用户口令 + 32B 盐 PBKDF2-SHA-512 派生 256 位 AES-CBC KEK 密钥加密密钥 (RFC 3211) 2. 载荷封装 随机 256 位 CEK 内容加密密钥 (AES-GCM) CMS 封装结构 12B Nonce + 16B 认证标签 3. 输出目标 单文件自解密 HTML 免装客户端 / 离线运行 内嵌 PEM 编码 CMS 载荷 OpenSSL 独立解密 CLI 直接调用原生验证

最关键的突破正是兼容性:生成的自解密 HTML 内部内嵌的是标准 PEM 格式 CMS 载荷。这意味着使用者既能直接双击在网页里输密码,也能在彻底脱离前端环境时,直接敲下一行标准命令解包:

openssl cms -decrypt -pwri_password

这一行命令把纯网页的“免配置交付”和企业级运维的“独立可审计”打通了。加密文件不再依赖特定网页存活,哪怕五年后这个前端代码跑不起来,标准命令行工具依然能无损提纯出原始数据。

零依赖的权衡:内存与抗算力上限

工程选择从来没有免费午餐。同赛道成熟工具 hat.sh 选用的是抗 GPU/ASIC 并行爆破能力更出色的 Argon2id 内存硬化算法和 XChaCha20-Poly1305,并支持流式分块传输。但代价很明显:接收端必须依赖特定的解密环境,无法直接单文件点开即用。

Apeleg 放弃 Argon2id 而坚守 PBKDF2-HMAC-SHA-512,目的只有一个:完全借力现代浏览器原生提供的 Web Crypto API,实现零第三方依赖打包。

核心架构权衡与技术指标 OWASP 推荐基准 600k PBKDF2-SHA-256 最低迭代建议 缺乏内存硬化机制 抗专用硬件爆破弱于 Argon2id Web Crypto 理论上限 64 GiB AES-GCM 单次操作理论极限 受制于宿主全量加载 全内存拼装易引发 OOM 崩溃 格式标准化程度 RFC 5652 对齐 OpenSSL CMS 规范 拒绝私有 JSON 封装 赋予载荷独立审计与归档能力

OWASP 密码存储指南目前首选 Argon2id;若受制于兼容性必须采用 PBKDF2,即便选用 SHA-256 也建议至少 600,000 次迭代。PBKDF2 没有内存硬化特性,面对定制硬件的并行破解算力相对脆弱。

另一个现实短板在内存分配。虽然 Web Crypto 规范指出 AES-GCM 的理论加密上限约为 64 GiB,但因为该项目没有像 Zix 那样支持文件夹流式归档或 hat.sh 的分块管道,而是采取一次性全量加载组装方案,大文件打包时受宿主浏览器可用内存直接制约,在移动设备或低配终端上很容易触发内存溢出崩溃。

  • 结论.对于 GB 级大文件归档,流式加密工具仍是首选;但在数百兆以内、极度依赖即开即解的离线分发场景下,遵照 CMS 规范的自解密 HTML 填补了极具工业价值的空白。

信任悖论:当密文退化成代码

技术方案跑得通,安全边界却变了味。

为了加固运行时,项目配置了严格的内容安全策略(CSP)阻断外部资源与网络连接,并引入防帧劫持(frame-busting)检查和沙箱加密。但在实际执行中存在一条妥协逻辑:如果浏览器沙箱没有暴露出 Web Crypto 接口,加密函数可能会回退由父文档注入,直接拉低沙箱本身的隔离效果。

投递给接收者的不再是静止的数据,而是一段必须当场执行的程序。

古人讲求“借箸代筹”,指望借别人的筷子帮自己画策,前提是筷子本身没被动过手脚。自解密 HTML 最隐秘的风险正在于此:它将静态密文变成了前端可执行文件。在不可控的端点设备上,只要宿主环境带毒、浏览器插件被注入恶意脚本,或者网页文件在传输链条中被掉包伪造了 UI,用户在页面上输入主密码的瞬间,密钥与明文就一并失守。

  • 风险.企业安全网关和防御团队需要提防攻击者借用这种合规格式绕过杀毒引擎探测,将其改造成天然免杀的凭据钓鱼载荷。

免装工具的便携红利,终究要用宿主环境的盲目信任来兑换。把它当作敏感离线通信的一把特制信封足够称职,但若以为把密文包装成网页就等于高枕无忧,那未免把复杂攻防想得太轻巧了。