我知道如何加密和解密一个NSData
,但这需要先将整个文件加载到内存中。
假设我有一个名为data.dat.enc
的50mb加密文件,我如何才能将其解密为data.dat
文件,而不必首先将其全部加载到内存中?
发布于 2012-03-16 05:45:33
编辑:此代码已由http://github.com/rnapier/RNCryptor扩展。
RNCryptManager就是一个很好的例子。它来自iOS5:PTL的第11章示例代码。请看:
+ (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
来完成任务。
发布于 2012-03-16 02:19:54
您有两种选择(这里我只描述加密过程,但解密过程类似):
使用流密码(如AES-CTR)
您使用16字节的密钥初始化密码,并使用真正的随机16字节随机数,写入随机数,加载第一个片段,加密它,写入结果,加载第二个片段,依此类推。请注意,您只能初始化密码一次。块的大小可以是任意的;它甚至不需要每次都是相同的。
使用具有一次通过链接模式的块密码,例如AES128-CBC
您使用16字节密钥初始化密码,生成一个随机的16字节IV,写入IV,写入文件的总长度,加载第一个片段,将其与IV一起加密,写入结果,加载第二个片段,使用前一个加密块的最后16个字节加密作为IV,写入结果,依此类推。片段的大小必须是16字节的倍数;同样,它甚至不需要每次都是相同的。您可能需要用零填充最后一个块。
两种情况下的都是
您必须计算原始未加密文件的加密哈希(例如,使用SHA-256),并在加密完成后写入。这非常简单:您在一开始就初始化散列,并在它加载后立即将每个块提供给它(包括nonce/IV和可能的长度字段)。在解密端,您也可以做同样的事情。最后,您必须验证计算的摘要是否与加密文件附带的摘要匹配。
如何在iOS上做到这一点?恐怕我不熟悉这个平台,但CCCypt似乎符合要求。
编辑: nonce/IV和length也是散列的。
https://stackoverflow.com/questions/9724851
复制相似问题