CCCrypt崩溃(EXC_BAD_ACCESS)

时间:2013-10-05 20:08:50

标签: ios objective-c encryption cryptography exc-bad-access

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

这是我的解密代码:

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){

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

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

由于

1 个答案:

答案 0 :(得分:1)

来自docs

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){
    ...
});

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