IOS – 如果文件太大而无法将所有文件加载到内存中,我如何解密一个大文件?

我知道如何AESencryption和解密一个NSData ,但是这需要首先将整个文件加载到内存中。

假设我有一个名为data.dat.enc的50mbencryption文件,我怎样才能解密它到一个文件data.dat而不必首先加载到内存?

编辑:此代码已被http://github.com/rnapier/RNCryptor扩大。


RNCryptManager是如何做到这一点的一个很好的例子。 它来自iOS5的第11章示例代码:PTL 。 看着:

 + (BOOL)decryptFromStream:(NSInputStream *)fromStream toStream:(NSOutputStream *)toStream password:(NSString *)password error:(NSError **)error; 

它假定盐和IV已经被预置在stream中(这在书中都有解释)。 有关AESencryption的更多一般性讨论,请参阅使用CommonCrypto正确encryptionAES 。

有关其使用的示例,请参阅同一项目中的CPCryptController.m 。

如果有足够的兴趣,我可以把这个对象作为一个独立的项目来支持,而不仅仅是一个示例代码。 这似乎对人们合理有用。 但是,按原样进行整合并不难。

更一般的答案是你用CCCryptorCreate创build一个encryption,然后调用每个块的CCCryptorUpdate 。 然后你打电话给CCCryptorFinal完成事情。

你有两个select(在这里我只描述encryption过程,但解密是相似的):

使用stream密码(如AES-CTR)

你用一个16字节的密钥和真正的随机的16字节的随机数来初始化密码,写入随机数,加载第一块,encryption,写入结果,加载第二块,等等。 请注意,您只能初始化密码一次。 片断的大小可以是任意的; 它甚至不需要每次都是一样的。

使用单通道链接模式的分组密码,例如AES128-CBC

你用16字节的密钥初始化密码,生成一个随机的16字节的IV,写入IV,写出文件的总长度,加载第一块,与IV一起encryption,写入结果,加载第二块, 使用前一个encryption块的最后16个字节作为IV进行encryption ,写入结果等等。 块的大小必须是16个字节的倍数; 再次,它甚至不需要每次都是一样的。 您可能需要用零填充最后一个块。

在这两种情况下

您必须计算原始未encryption文件的encryption散列(例如,使用SHA-256),并在encryption完成时写入它。 这很简单:初始化哈希,并在加载后立即将其加载(包括nonce / IV和可能的长度字段)。 在解密方面,你也这样做。 最终,您必须确认计算出的摘要与encryption文件附带的摘要匹配。

这怎么可以在iOS上完成? 恐怕我不熟悉这个平台,但是CCCypt似乎符合这个法案。

编辑:随机数/四和长度也被散列。