当前位置: 首页 > 知识库问答 >
问题:

RNDecryptor addData方法中的混淆

王亮
2023-03-14
- (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。

提前道谢。

共有1个答案

黄流觞
2023-03-14

问题是流通常不知道剩下多少数据。在您的情况下,似乎验证标记(HMAC值)被发送密文的一方放在了密文的末尾。

现在的问题是,您应该只更新数据,而不是身份验证标记。由于您不知道还有多少数据可用,可能是您已经在读入末尾的身份验证标记。显然,如果在计算中包含HMAC本身的输出,HMAC计算将失败。

所以基本上您读取流并更新HMAC状态直到结束。然后执行最后一次HMAC更新,直到密文结束。从流的末尾提取给定的身份验证标记,然后比较计算值和给定值。如果它们是相同的,那么将检查密文(以及明文)的完整性和身份验证--当然,假定密钥从未泄露给攻击者。

 类似资料:
  • 但如果我用: 如果需要,我很乐意提供整个SSCE,但目前,为了让事情更简短,下面是TableModel的getValueAt()和setValueAt()方法: 数据只是Person类型的arraylist(一个具有明显变量(String)fName、(String)sName和(LocalDate)DOB的类) 任何帮助都将不胜感激!

  • 我已经通过字符串的拆分方法留档,但结果并不像预期的那样。当我们将限制参数设置为负值的字符串拆分时,它总是附加一个空值。为何要这样做呢?考虑一些案例 我希望这两张照片都是3。 现在,由于没有找到匹配项,通常的split with limit方法应该打印0,但它创建了一个带有空字符串的数组。 现在我有了一个匹配项,无限制参数的split方法可以很好地工作。它是我预期的输出,但为什么它不在本例中创建一个

  • 我尝试在android studio中使用Proguard,但Proguard似乎没有混淆类名,例如,我的应用程序结构和配置: 和配置 但当我尝试在应用程序中触发异常时: ADB控制台中列出了异常: 只有方法被混淆了,MainActivity.class没有

  • 我知道System类的System.In是InputStream的一个具体子类的实例,因为InputStream的read()方法是抽象的,System.In必须重写这个方法。根据关于InputStream的read()方法的文档: 从输入流中读取下一个字节的数据。值字节以0到255范围内的int形式返回。如果由于已到达流的结尾而没有可用的字节,则返回值-1。此方法将阻塞,直到输入数据可用、检测到

  • 问题内容: 我可以通过设置为来解决此问题,但是对此我有一些疑问 当我将fetchSize设置为10或其他正整数时,它不起作用,将其设置为有效后,为什么呢? 如果我们设置负值,则它给非法值错误,但就是那么,为什么不给错误? 该表包含600万条记录,在获取100或200条记录后我关闭了该表,这需要30-35秒的时间。 减少关闭时间的解决方案。 我想在此处添加更多内容,并已使用MySQL驱动程序对其进行

  • 问题内容: 我对从方法中看到的一些简单行为感到困惑。 我有一个名为的文件,看起来像这样: 我写了这个脚本: my.js 脚本输出: 我想增强脚本,使其充满而不是空着。 当我使用逐步浏览脚本时,似乎正在填充,但我认为这是一种幻想。 另外,当我运行 时, 在读取之前运行。 因此,我可能需要在这里了解一些异步机制。 对于那些了解得很好的人,以下问题可能很容易。 但是,我很乐意得到这个问题的答案: 如何增