ios - CCCrypt 崩溃(EXC_BAD_ACCESS)

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

我正在尝试解码一些数据,但是当数据大于 520,000(字节?它是 [数据长度])时,我的应用程序将在 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){

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

为什么会这样,有什么方法可以让它在后台线程上运行吗?

谢谢

最佳答案

来自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应该是前一个参数的长度,它应该等于输入大小加上一个 block 的大小。

For stream ciphers, the output size is always equal to the input size, and CCCryptorFinal() never produces any data. For block ciphers, the output size will always be less than or equal to the input size plus the size of one block.

因此,就您的情况而言,您应该定义 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){
    ...
});

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

关于ios - CCCrypt 崩溃(EXC_BAD_ACCESS),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19202193/

相关文章:

ios - objective c 安全头文件

ios - 有人可以解释为什么我不能从此方法返回值吗?

iphone - MPMoviePlayerController 慢速前进和后退运动

ios - 从 iOS 应用程序与 Facebook 分享超链接

amazon-web-services - 如何通过 CLI 加密 Lambda 的环境变量?

ios - 如何在自定义 UISlider 中在 slider 值 0 之前和 slider 值 100 之后提供填充

ios - NSURLConnection 失败,没有错误

objective-c - 如何遍历多维 NSArray?

Java 密码和 php mcrypt_encrypt(带 ECB 填充的 BLOWFISH 算法)

python - python中最好/最容易使用的加密库是什么