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

时间:2012-03-15 17:18:49

标签: iphone ios encryption cryptography

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

假设我有一个名为data.dat.enc的50mb加密文件,如何将其解密为文件data.dat而无需先将其全部加载到内存中?

2 个答案:

答案 0 :(得分:15)

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


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

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

它假定盐和IV已经被添加到流中(这在书中已经解释过了)。有关AES加密的更一般性讨论,请参阅Properly encrypting with AES with CommonCrypto

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

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

更一般的答案是您使用CCCryptorCreate创建一个加密,然后为每个块调用CCCryptorUpdate。然后你打电话给CCCryptorFinal完成任务。

答案 1 :(得分:0)

您有两种选择(这里我只描述加密过程,但解密类似):

使用流密码(如AES-CTR)

使用16字节密钥和真正随机16字节nonce初始化密码,写入nonce,加载第一部分,加密,写入结果,加载第二部分等等。 请注意,您必须只初始化一次密码。片的大小可以是任意的; 它甚至不需要每次都相同。

使用具有一次通过链接模式的分组密码,例如AES128-CBC

用16字节密钥初始化密码,生成一个随机的16字节IV,写入IV,写入文件的总长度,加载第一块,与IV一起加密,写入结果,加载一个第二部分,使用前一个加密块的最后16个字节加密 作为IV,写入结果,依此类推。该片段的大小必须是16字节的倍数;再次,它甚至不需要每次都相同。您可能需要用零填充最后一个块。

在这两种情况下

您必须计算原始未加密文件的加密哈希值(例如,使用SHA-256),并在加密完成后写入。这很简单:您在开始时初始化哈希值,并在加载后立即将每个块提供给它(包括nonce / IV和可能的长度字段)。在解密方面,你也这样做。最后,您必须验证计算的摘要是否与加密文件附带的摘要匹配。

如何在iOS上完成?我担心我对平台不熟悉,但CCCypt似乎符合要求。

编辑:nonce / IV和长度也被哈希。