0

我正在尝试解码一些数据,但是当数据大于 520,000(字节?它是[data length])我的应用程序将CCCrypt在线上的调试器上崩溃,或者如果与调试器分离,它只是冻结并且实际上并没有正确崩溃(Spinner 继续运行但应用程序完全冻结)。

这是我的解密代码:

char *key = ENCRYPTION_KEY;
NSUInteger dataLength = [data length];
uint8_t unencryptedData[dataLength + kCCKeySizeAES128];
size_t unencryptedLength;
CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionECBMode, key, kCCKeySizeAES128, NULL, [data bytes], dataLength, unencryptedData, dataLength, &unencryptedLength);
NSData *output = [[NSData alloc] initWithBytes:unencryptedData length:unencryptedLength];

return output;

编辑 - - - - -

按照下面 Hejazi 的回答,我现在有了这个,但它仍然不起作用:(

- (NSData *)decodeSnapDataInBackground:(NSData *)data
{
    char *key = ENCRYPTION_KEY;
    NSUInteger dataLength = [data length];
    uint8_t unencryptedData[dataLength + kCCBlockSizeAES128];
    size_t unencryptedLength;
    size_t unencryptedDataLength = dataLength + kCCBlockSizeAES128;
    CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionECBMode, key, kCCKeySizeAES128, NULL, [data bytes], dataLength, unencryptedData, unencryptedDataLength, &unencryptedLength);
    NSData *output = [[NSData alloc] initWithBytes:unencryptedData length:unencryptedLength];

    return output;
}

编辑 2 -----

当我在后台线程上执行解码时,似乎会出现此问题。我正在使用这个:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){

当我删除它时,它现在可以很好地解码大块数据。

为什么会这样,有什么办法可以让它在后台线程上工作?

谢谢

4

1 回答 1

1

来自文档

CCCrypt(CCOperation op, CCAlgorithm alg, CCOptions options,
     const void *key, size_t keyLength, const void *iv,
     const void *dataIn, size_t dataInLength, void *dataOut,
     size_t dataOutAvailable, size_t *dataOutMoved);

倒数第二个参数dataOutAvailable应该是前一个参数的长度,应该等于输入大小加上一个块的大小。

对于流密码,输出大小始终等于输入大小,并且 CCCryptorFinal() 从不产生任何数据。对于分组密码,输出大小将始终小于或等于输入大小加上一个块的大小。

因此,在您的情况下,您应该定义unencryptedData如下:

uint8_t unencryptedData[dataLength + kCCBlockSizeAES128];
/// kCCBlockSizeAES128 instead of kCCKeySizeAES128

并传递unencryptedData数组的长度而不是输入数据的长度:

size_t unencryptedDataLength = dataLength + kCCBlockSizeAES128;
CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionECBMode, key, 
        kCCKeySizeAES128, NULL, [data bytes], dataLength, 
       unencryptedData, unencryptedDataLength, &unencryptedLength);

顺便说一句,您可以使用RNCryptor库,它是 iOS 和 Mac 的 CCCryptor 包装器。

更新

尝试在单个串行调度队列上运行所有后台解密操作。创建串行调度队列:

dispatch_queue_t decryptionQueue = dispatch_queue_create("DecryptionQueue", NULL);

然后使用它代替您使用的全局队列:

dispatch_async(decryptionQueue, ^(void){
    ...
});

确保使用相同的队列,而不是每次都创建一个新队列。

于 2013-10-05T20:48:43.237 回答