我正在尝试解码一些数据,但是当数据大于 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/