AES在iOS中加密大文件

AES在iOS中加密大文件,ios,aes,large-data,Ios,Aes,Large Data,我正在创建一个聊天应用程序,其中我必须加密一个大型视频,并根据需要解密它。我正在使用以下代码,但由于内存限制,它在大文件上崩溃。有没有其他方法可以加密大文件,使其不会崩溃 + (NSData *)addPaddingToData:(NSData *)data paddingKey:(NSString *)keyString paddingiv:(NSString *)ivString { NSArray * chu

我正在创建一个聊天应用程序,其中我必须加密一个大型视频,并根据需要解密它。我正在使用以下代码,但由于内存限制,它在大文件上崩溃。有没有其他方法可以加密大文件,使其不会崩溃

+ (NSData *)addPaddingToData:(NSData *)data
                  paddingKey:(NSString *)keyString
                   paddingiv:(NSString *)ivString {
    NSArray * chunkedArray = [NSData chunkedArrayForData:data chunkSize:10240];

    NSMutableData *mutableData = [[NSMutableData alloc] init];

    for (NSData *d in chunkedArray) {
        NSData * encryptedData = [[StringEncryption alloc] encrypt:d key:keyString iv:ivString];
        [mutableData appendData:encryptedData];
    }

    return (NSData *)mutableData;
}

+ (NSData *)removePaddingToData:(NSData *)data
                     paddingKey:(NSString *)keyString
                      paddingiv:(NSString *)ivString {
    NSArray * chunkedArray = [NSData chunkedArrayForData:data chunkSize:10256];
    NSMutableData *mutableData = [[NSMutableData alloc] init];

    for (NSData *d in chunkedArray) {
        NSData *decryptedData = [[StringEncryption alloc] decrypt:d  key:keyString iv:ivString];
        [mutableData appendData:decryptedData];
    }

    return (NSData *)mutableData;
}

+ (NSArray *)chunkedArrayForData:(NSData *)data chunkSize:(NSUInteger)size {
    NSUInteger length = [data length];
    NSUInteger chunkSize = size;
    NSUInteger offset = 0;
    NSMutableArray * chunkedArray = [[NSMutableArray alloc] init];
    do {
        NSUInteger thisChunkSize = length - offset > chunkSize ? chunkSize : length - offset;
        NSData *chunk = [NSData dataWithBytesNoCopy:(char *)[data bytes] + offset
                                             length:thisChunkSize
                                       freeWhenDone:NO];
        offset += thisChunkSize;
        [chunkedArray addObject:chunk];
    } while (offset < length);

    return chunkedArray;
}
+(NSData*)添加填充数据:(NSData*)数据
paddingKey:(NSString*)键串
填充IV:(NSString*)ivString{
NSArray*chunkedArray=[NSData chunkedArrayForData:data chunkSize:10240];
NSMutableData*mutableData=[[NSMutableData alloc]init];
用于(NSData*d在chunkedArray中){
NSData*encryptedData=[[StringEncryption alloc]encrypt:d key:keyString iv:ivString];
[mutableData appendData:encryptedData];
}
返回(NSData*)可变数据;
}
+(NSData*)删除PaddingToData:(NSData*)数据
paddingKey:(NSString*)键串
填充IV:(NSString*)ivString{
NSArray*chunkedArray=[NSData chunkedArrayForData:data chunkSize:10256];
NSMutableData*mutableData=[[NSMutableData alloc]init];
用于(NSData*d在chunkedArray中){
NSData*decryptedData=[[StringEncryption alloc]decrypt:d key:keyString iv:ivString];
[mutableData appendData:decryptedData];
}
返回(NSData*)可变数据;
}
+(NSArray*)chunkedArrayForData:(NSData*)数据块大小:(nsInteger)大小{
NSU整数长度=[数据长度];
nsu整数chunkSize=大小;
整数偏移=0;
NSMutableArray*ChunkeArray=[[NSMutableArray alloc]init];
做{
NSUInteger thisChunkSize=长度-偏移>chunkSize?chunkSize:长度-偏移;
NSData*chunk=[NSData dataWithBytesNoCopy:(字符*)[data bytes]+偏移量
长度:thisChunkSize
freeWhenDone:否];
偏移量+=此块大小;
[chunkedArray添加对象:chunk];
}而(偏移量<长度);
返回chunkedArray;
}

使用一次只读取一小段文件的流

当前代码读取最初要加密的整个文件,将整个文件逐块加密到
mutableData
实例中。最后,您可以将未加密和加密数据的内容同时存储在内存中。使用块不会减少内存占用

这种“分块”方法还有另一个问题,
StringEncryption
类很可能不仅扩展了加密,而且对每个分块使用相同的iv重新启动。这不会产生与单个加密相同的加密输出

要使用流,请为输入和输出创建一个
NSStream
实例。使用普通密码,但不在无状态下使用,一次性使用,而是使用
CCCryptorCreate
CCCryptorUpdate
CCCryptorFinal

  • 创建输入/输出流(
    NSInputStream
    NSOutputStream
  • 首先使用
    CCCryptorCreate
    创建上下文
  • 循环从steam读取一些数据,使用该数据调用
    CCCryptorUpdate
    ,并将结果写入流
  • 如果使用了填充,则调用
    CCCryptorFinal
    并将最终数据写入流
  • 关闭溪流
这样,在任何时候只有一小部分文件在内存中


像往常一样,您应该查看该解决方案是否符合您的需要。

什么是“StringEncryption”类?这有点令人不安,因为加密的是数据,而不是字符串。