HEREの ObjectiveC の RNDecryptor クラスには、次のようにファイルをチャンクで復号化する機能があります。
- (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);
}
また、RNDecryptor の addData メソッドは次のとおりです。
- (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 バイトはどうなりますか?
このコードは証明されているので混乱しているかもしれませんが、これを理解したいです。
前もって感謝します。