Encryption 文件结尾缺少RNCryptor字节
使用RNCryptor对文件进行加密和解密时出现了一个问题,我似乎无法取回完整的文件 我的密码如下Encryption 文件结尾缺少RNCryptor字节,encryption,rncryptor,Encryption,Rncryptor,使用RNCryptor对文件进行加密和解密时出现了一个问题,我似乎无法取回完整的文件 我的密码如下 - (void) encryptDownloadedFile:(NSString*)filename { NSString *outputTmpFilePath = [downloadCacheDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mov", filename]]; int
- (void) encryptDownloadedFile:(NSString*)filename
{
NSString *outputTmpFilePath = [downloadCacheDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mov", filename]];
int blockSize = 32 * 1024;
__block NSInputStream *plainTextStream = [NSInputStream inputStreamWithData:[downloadFileStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey]];
__block NSOutputStream *encryptedStream = [NSOutputStream outputStreamToFileAtPath:outputTmpFilePath append:NO];
__block NSMutableData *downloadedFileData = [NSMutableData data];
[plainTextStream open];
[encryptedStream open];
__block NSMutableData *data = [NSMutableData dataWithLength:blockSize];
__block RNEncryptor *encryptor = nil;
dispatch_block_t readStreamBlock = ^{
[data setLength:blockSize];
NSInteger bytesRead = [plainTextStream read:[data mutableBytes] maxLength:blockSize];
if (bytesRead < 0) {
// Throw an error
}
else if (bytesRead == 0) {
[encryptor finish];
[downloadedFileData writeToFile:outputTmpFilePath atomically:YES];
[plainTextStream close];
[encryptedStream close];
[downloadFileStream close];
plainTextStream = nil;
encryptedStream = nil;
downloadFileStream = nil;
}
else {
[data setLength:bytesRead];
[encryptor addData:data];
}
};
encryptor = [[RNEncryptor alloc] initWithSettings:kRNCryptorAES256Settings
password:@"blah"
handler:^(RNCryptor *cryptor, NSData *data) {
[downloadedFileData appendBytes:data.bytes length:data.length];
if (cryptor.isFinished) {
}
else {
readStreamBlock();
}
}];
readStreamBlock();
}
完整性解密在这里
- (void) decryptDownloadedFile:(NSString*)filename
{
NSString *inputTmpFilePath = [downloadCacheDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mov", filename]];
NSString *outputTmpFilePath = [downloadCacheDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"decrypted%@.mov", filename]];
int blockSize = 32 * 1024;
NSInputStream *cryptedStream = [NSInputStream inputStreamWithFileAtPath:inputTmpFilePath];
NSOutputStream *decryptedStream = [NSOutputStream outputStreamToFileAtPath:outputTmpFilePath append:NO];
[cryptedStream open];
[decryptedStream open];
__block NSMutableData *data = [NSMutableData dataWithLength:blockSize];
__block RNDecryptor *decryptor = nil;
dispatch_block_t readStreamBlock = ^{
[data setLength:blockSize];
NSInteger bytesRead = [cryptedStream read:[data mutableBytes] maxLength:blockSize];
if (bytesRead < 0) {
// Throw an error
}
else if (bytesRead == 0) {
[decryptor finish];
[decryptedStream close];
}
else {
[data setLength:bytesRead];
[decryptor addData:data];
}
};
decryptor = [[RNDecryptor alloc] initWithPassword:@"blah"
handler:^(RNCryptor *cryptor, NSData *data) {
[decryptedStream write:data.bytes maxLength:data.length];
if (cryptor.isFinished) {
}
else {
readStreamBlock();
}
}];
readStreamBlock();
}
如果我把它和前面的解决方案混合在一起,我会遇到同样的问题 您将流移近了,这可能就是问题所在。在链接的示例中,在
readStreamBlock
中,有以下代码:
else if (bytesRead == 0) {
[decryptor finish];
}
if (cryptor.isFinished) {
[decryptedStream close];
// call my delegate that I'm finished with decrypting
}
然后在解密处理程序中,有以下代码:
else if (bytesRead == 0) {
[decryptor finish];
}
if (cryptor.isFinished) {
[decryptedStream close];
// call my delegate that I'm finished with decrypting
}
您已将关闭移动到readStreamBlock
:
else if (bytesRead == 0) {
[decryptor finish];
[decryptedStream close];
}
这意味着流在异步解密完成之前关闭。我不擅长读取Objective-C-但我知道最终解密的症状。。您是否记得在调用finish之后获取解密程序生成的最后一个加密数据?解密程序模块保留最后一位数据,直到可以确定它是填充数据还是真实数据。Ebbe返回到RNCryptor finishWithError中的CCCryptorFinal,但据我所知,它似乎在做预期的事情。我现在已经停止了这个,以后可能还会继续。最后,我用一个fileMgr copyItemAtPath将输出从decryptedStream复制到另一个文件。这似乎从它们隐藏的地方清除了最后的几个字节。如果有人有更好的解决方案,请告诉我。这似乎不是问题所在。我承认上面发布的代码有您注意到的变化,但正如您所描述的,我在代码中有相反的变化。对我来说,重要的是,在模拟器中运行close时,调用NSFileManager文件属性报告的已完成文件的大小(19614944)小于Finder显示的大小(19615005)。我开始认为这是一个NSOutputStream问题,因为复制前面提到的文件可以解决这个问题。此外,在处理这个问题的过程中,我不断遇到内存问题。我编写了自己的逐字节文件复制器来解决copyItemAtPath内存问题。但也将@autorelease池添加到RNCryptorEngine addData、RNDecryptor decryptData和RNEncryptor addData.Mea Culpa。今天早上我过得很愉快。Rob是正确的,尽管我在正确的位置关闭了流,但我没有做的是从同一位置调用文件处理的下一步,我在readStreamBlock中调用了它。因此,我的流程的下一步是在加密完成之前开始。我并没有在示例代码中实际展示这一点。