我正在尝试解码一些数据,但是当数据大于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){
当我删除它时,它现在可以很好地解码大块数据。
为什么会这样,并且有什么方法可以让它在后台线程上工作吗?
由于
答案 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){
...
});
确保使用相同的队列,而不是每次都创建一个新队列。