使用 WebCrypto API 加密大文件

use*_*470 5 javascript encryption webcrypto-api

我正在尝试使用WebCrypto API加密大文件(> 1GB)。

加密小文件效果很好,但是当我尝试加密大文件时,我的浏览器挂起,而且似乎加密从未完成。

我认为最好的选择是读取和加密文件的块,而不是在读取完成后将这些块合并在一起。

这里有人有加密和合并块的经验吗?如果是这样,如果有人可以向我展示示例或指出正确的更正,我将不胜感激。

提前致谢!

Maa*_*wes 5

显然,高级 WebCrypto API 的设计并未考虑流/大消息。但是,如果您查看常见的密码操作模式,那么您会发现可以使用不同的模式,以便连接不同的密文并获得完整的密文。

您可以对 1 MiB 块(或 16 字节的任意倍数)使用 AES-CBC,并使用密文的第一个到最后一个 16 字节作为 IV 来加密下一个块。您将必须忽略最后一个块,因为它包含任何块的加密填充,当然最后一个块除外。不幸的是,这不是一种完整性/身份验证模式,并且结果很容易受到 padding oracle 攻击,所以我仍然不推荐它。此外,当您忽略填充时,您无法使用相同的方法解密。

同样,您可以将计数器 (CTR) 模式与计数器一起使用,并从计数器值开始<nonce>|0000000000000000,然后在 1 MiB 后继续使用计数器值加密<nonce>|0000000000010000(因为 1 MiB 包含 65536 个块),然后<nonce>|0000000000020000在 2 MiB 后使用,等等。随机数是唯一的先前 IV/初始计数器块中的 8 字节值。该密码在加密和解密之间具有完美的对称性,并且不使用填充。然而,它很容易受到对手的改变;基本上,对手可以翻转密文中的任何字节,从而翻转明文中的任何位。这还可能导致进一步的明文预言并泄露更多信息。

请注意,您不能对 AEAD 密码(例如 GCM)执行同样的操作。在这种情况下,您需要使用随机数和身份验证标签来扩展密文。但您仍然可以加密 1 MiB,并将其扩展为 12 字节随机数、1 MiB 密文和 16 字节身份验证标签。然后,您可以使用更大的块大小进行解密并获取 1 MiB 明文块。请注意,您仍然必须对身份验证标签执行 MAC,否则攻击者可能会对 1 MiB + 28B 大小的块进行重新排序。一种方法是使用身份验证标签作为 AAD 输入来执行 0 字节 GCM 加密。

哎呀,我想这就是你在超出其初衷之外使用 API 所得到的结果。这是完全有可能的,但是,是的,我想需要一些研究。


此处使用 1 MiB 表示 1024 x 1024 字节,或 1024 KiB。Mega 的意思是“百万”,而不是——呃,我又忘记了确切的数字。

  • 1. 嗯,是的,您可以对所有字节执行 HMAC。但是,如果该函数也只允许完整消息输入,那么您可能需要使用 Merkle 列表等在块上创建哈希,然后对哈希值执行 HMAC。2. 您只需忽略块之间的虚假填充。上述方案的结果与正常的 CBC 密文相同。因此接收方可以使用任何提供(分段)CBC 解密的函数。 (2认同)