Класс RNDecryptor в ObjectiveC по адресу ЗДЕСЬ имеет функцию расшифровки файла по частям следующим образом:
- (IBAction)decryptWithSemaphore:(id)sender {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block int total = 0;
int blockSize = 32 * 1024;
NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *input = [[docPaths objectAtIndex:0] stringByAppendingPathComponent:@"zhuge.rncryptor"];
NSString *output = [[docPaths objectAtIndex:0] stringByAppendingPathComponent:@"zhuge.decrypted.pdf"];
NSInputStream *cryptedStream = [NSInputStream inputStreamWithFileAtPath:input];
__block NSOutputStream *decryptedStream = [NSOutputStream outputStreamToFileAtPath:output append:NO];
__block NSError *decryptionError = nil;
[cryptedStream open];
[decryptedStream open];
RNDecryptor *decryptor = [[RNDecryptor alloc] initWithPassword:@"12345678901234567890123456789012" handler:^(RNCryptor *cryptor, NSData *data) {
@autoreleasepool {
NSLog(@"Decryptor recevied %d bytes", data.length);
[decryptedStream write:data.bytes maxLength:data.length];
dispatch_semaphore_signal(semaphore);
data = nil;
if (cryptor.isFinished) {
[decryptedStream close];
decryptionError = cryptor.error;
// call my delegate that I'm finished with decrypting
}
}
}];
while (cryptedStream.hasBytesAvailable) {
@autoreleasepool {
uint8_t buf[blockSize];
NSUInteger bytesRead = [cryptedStream read:buf maxLength:blockSize];
if (bytesRead > 0) {
NSData *data = [NSData dataWithBytes:buf length:bytesRead];
total = total + bytesRead;
[decryptor addData:data];
NSLog(@"New bytes to decryptor: %d Total: %d", bytesRead, total);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
}
}
[cryptedStream close];
[decryptor finish];
dispatch_release(semaphore);
}
И метод addData RNDecryptor выглядит следующим образом:
- (void)addData:(NSData *)theData
{
if (self.isFinished) {
return;
}
[self.inData appendData:theData];
if (!self.engine) {
[self consumeHeaderFromData:self.inData];
}
if (self.engine) {
NSUInteger HMACLength = self.HMACLength;
if (self.inData.length > HMACLength) {
NSData *data = [self.inData _RNConsumeToIndex:self.inData.length - HMACLength];
[self decryptData:data];
}
}
}
Я не понимаю, что на самом деле пытается сделать эта строка, которая вызывается для каждого фрагмента зашифрованного потока:
NSData *data = [self.inData _RNConsumeToIndex:self.inData.length - HMACLength];
Допустим, у меня есть размер блока 1000 байт, а HMACLength — 32.
Если я попытаюсь расшифровать файл, размер которого превышает размер блока, скажем, 5000 байт, тогда этот метод addData запустит первую итерацию, как это
NSData *data = [self.inData _RNConsumeToIndex:1000 - 32];
то есть после потребления заголовков зашифрованные байты от индекса 0 до (1000-32), но хэш записывается в конце зашифрованного потока, последние несколько байтов, а не с каждым фрагментом. и на следующей итерации входной поток будет считывать следующие 1000 байтов, что произойдет с 32 байтами, которые были обрезаны из фрагмента первой итерации?
Может быть, я запутался, так как этот код проверен, но я хочу это понять.
Заранее спасибо.