【问题标题】:encrypting and/or decrypting large files (AES) on a memory and storage constrained system, with "catastrophe recovery"使用“灾难恢复”在内存和存储受限的系统上加密和/或解密大文件 (AES)
【发布时间】:2012-07-02 19:42:07
【问题描述】:

我有一个相当笼统的问题,如果有点含糊,请见谅。

所以,我们假设一个 1GB 的文件,需要在给定系统上加密然后解密。

问题是系统只有不到 512 MB 的可用内存和大约 1.5 GB 的存储空间(给予或接受),因此,对于“板载”文件,我们有大约 500 MB 的“硬盘暂存空间”和小于 512 mb RAM 可以“玩”。

系统在加密或解密过程中的任何时候都不太可能出现“计划外掉电”,并且需要在再次上电后能够成功恢复加密/解密过程(这似乎是一个额外的 -难以解决的问题)。

问题是:

1) 是否可行:) ?

2) 最好的策略是什么

a) 使用如此小的暂存空间进行加密/解密(在解密/加密时不能将整个文件放在周围,需要以某种方式“即时”截断它......)

b) 实施可以在这种受限环境中工作的灾难恢复?

附: 使用的密码必须是 AES。

我专门研究了 AES-CTR,但在无法将整个解密文件保留到最后的环境中,灾难恢复恶作剧似乎并不是那么好......

[编辑添加] 我想我还是会按照 Iserni 的方式来做。

【问题讨论】:

  • CBC 没有什么是 CTR 没有的。除了诚信CTR这样的方案肯定是一个非常不错的选择。

标签: encryption cryptography aes large-files on-the-fly


【解决方案1】:

这是可行的,前提是您有办法将 AES 状态向量与文件位置一起保存。

  1. 将 AES 状态和文件位置 P 保存到文件 STAGE1 和 STAGE2
  2. 读取一大块(例如 10 兆字节)的加密/解密数据
  3. 将解密/加密块写入外部暂存器 SCRATCH
  4. 记录 SCRATCH 已完成的事实
  5. 在原文件的相同位置写入 SCRATCH
  6. 记录 SCRATCH 已成功复制的事实
  7. 转到 1

如果您在第 1 阶段之后遇到严重崩溃,并且 STAGE1 和 STAGE2 不同意,您只需重新启动并假设 P 最早的阶段是好的。 如果您在第 2 阶段期间或之后发生严重崩溃,您将损失 10 兆字节的工作:但是 AES 和 P 很好,所以您只需重复第 2 阶段。 如果您在第 3 阶段崩溃,那么在恢复时您将找不到第 4 阶段的标记,因此会知道 SCRATCH 不可靠,必须重新生成。拥有 STAGE1/STAGE2,您可以这样做。 如果你在第 4 阶段崩溃,你会相信 SCRATCH 必须重新生成,即使你可以避免这种情况——但你在重新生成过程中不会损失什么,除了一点点时间。 出于同样的原因,如果您在 5 期间崩溃,或者在 6 被提交到磁盘之前,您只需重复第 5 和 6 阶段。您知道您不必重新生成 SCRATCH,因为第 4 阶段已提交到磁盘。如果您在第 1 阶段后崩溃,您仍然可以复制一个好的 SCRATCH。

所有这些都假设 10 MB 大于缓存(如果写回,则为操作系统 + 硬盘)的数据价值。如果不是,请提高到 32 或 64 MB。恢复会相应地变慢。

如果这些函数可用,则在每个写入阶段完成后刷新()和同步()可能会有所帮助。

总的写入时间比正常的两倍多一点,因为需要“写入两次”才能确定。

【讨论】:

  • 所以...基本上,在加密时,我 1) 初始化 AES-CBC 2) 保存相关的加密信息 3) 从明文开头复制第一个 xMB 到草稿 4) 加密它们 5) 保存最后 16字节作为“下一步 AES 信息” 6)将加密的 10MB 写回源代码并开始处理下一个 10MB 的内容,在我进行时记录每一步,以便在崩溃后采取相应措施?看起来很聪明:)
  • 拥有更多磁盘空间来存储源文件和输出文件会大大提高性能。或者,如果文件可能被“分块”成 100 MB 的块 - 那么可以读取 PLAIN_1、写入 CRYPT_1、读取 PLAIN2、写入 CRYPT_2、删除 PLAIN_1 等等。最后,您将拥有所有 CRYPT_* 块,不需要额外的读取或写入,除了每个块末尾的单独“保证”(几个字节)。我认为它也更容易实现,而且 100MB 应该会击败大多数缓存方案。
  • 好吧,经过一番考虑,我想我会这样做。谢谢伊塞尔尼
【解决方案2】:

您必须分块处理大文件。断开文件的一部分,对其进行加密,然后将其保存到磁盘;保存后,丢弃未加密的部分。重复。要解密,抓取一个加密的片段,解密它,存储未加密的块。丢弃加密的片段。重复。完成解密后,将它们连接起来。

【讨论】:

  • 嗯...嗯,是的,它似乎可以使用 AES-CBC,因为每个下一个块基本上都是用前一个块的最后 16 个字节加密的,所以只要“最后一个好的加密块”或,在加密的情况下,“最后一个好的明文块”是已知的(通过某种日志技巧,比如有一个额外的文件来存储最近 10 次操作的数据),应该有一个直接的“灾难恢复”途径,amrite ?
【解决方案3】:

这当然是可行的。

“最大”(但一点也不大)的问题是,当您加密 128 Mb 的原始数据时,您需要将它们从源文件中删除。为此,您需要将文件的其余部分复制到开头,然后截断文件。这需要时间。在这一步可以关闭电源,但你并不在意——你知道你加密的数据的大小(如果你用大小为 16 字节的块加密数据,加密数据的大小将是等于从解密文件中删除或必须删除的大小)。不幸的是,发明这个方案似乎比解释它更容易:),但除了额外的复制操作会减慢进程之外,我真的没有看到任何问题。不,没有通用的方法可以从文件的开头剥离数据而不将其余部分复制到开头。

【讨论】:

  • 啊,是的,确实,截断只适用于文件结尾。但我明白你在说什么,我想 :) 谢谢,会尝试这样做(并使用所有复制到 badger 所产生的可恶性能来获得更大的硬盘驱动器......事情:))
  • 为什么不能直接将加密数据复制到纯数据上?你可以保存状态,不是吗?
  • @owlstead 万一发生电源故障,很有可能出现损坏或数据丢失。
  • 只是保存状态,映射文件,写入暂存器,保存状态,加密到原始状态并再次保存状态不起作用?当然你需要一个暂存器和状态,但是每次移动大部分文件似乎有点浪费(或者实际上,很多浪费)。
  • @owlstead 是的,这就是日志文件系统的工作方式(包括我们的 SolFS)。我不认为复制文件的其余部分会损坏原始文件,就像就地写入加密数据一样。所以你是对的,我的想法并不能保证不会发生文件损坏。
猜你喜欢
  • 1970-01-01
  • 2011-01-03
  • 2014-11-07
  • 2017-02-03
  • 1970-01-01
  • 2021-05-19
  • 1970-01-01
  • 1970-01-01
  • 2013-02-09
相关资源
最近更新 更多