Я пытаюсь использовать CommonCrypto для шифрования объекта NSMutableData на месте (копируя полученные байты себе без дублирования). Раньше я использовал «однократный» метод CCCrypt(), главным образом потому, что он казался простым. Я заметил, что мой объект данных дублируется в памяти. Чтобы избежать этого, я попытался использовать объект NSInputStream с размером буфера 2048 байт. Я читаю свой объект NSMutableData и постоянно вызываю CCCryptorUpdate() для обработки шифрования. Проблема в том, что он все еще кажется дублированным. Вот мой текущий код (обратите внимание, что это категория в NSMutableData — в основном по историческим причинам — таким образом, ссылки на «я»):
- (BOOL)encryptWithKey:(NSString *)key
{
// Key creation - not relevant to the dercribed problem
char * keyPtr = calloc(1, kCCKeySizeAES256+1);
[key getCString: keyPtr maxLength: sizeof(keyPtr) encoding: NSUTF8StringEncoding];
// Create cryptographic context for encryption
CCCryptorRef cryptor;
CCCryptorStatus status = CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES128, kCCOptionECBMode, keyPtr, kCCKeySizeAES256, NULL, &cryptor);
if (status != kCCSuccess)
{
MCLog(@"Failed to create a cryptographic context (%d CCCryptorStatus status).", status);
}
// Initialize the input stream
NSInputStream *inStream = [[NSInputStream alloc] initWithData:self];
[inStream open];
NSInteger result;
// BUFFER_LEN is a define 2048
uint8_t buffer[BUFFER_LEN];
size_t bytesWritten;
while ([inStream hasBytesAvailable])
{
result = [inStream read:buffer maxLength:BUFFER_LEN];
if (result > 0)
{
// Encryption goes here
status = CCCryptorUpdate(
cryptor, // Previously created cryptographic context
&result, // Input data
BUFFER_LEN, // Length of the input data
[self mutableBytes], // Result is written here
[self length], // Size of result
&bytesWritten // Number of bytes written
);
if (status != kCCSuccess)
{
MCLog(@"Error during data encryption (%d CCCryptorStatus status)", status);
}
}
else
{
// Error
}
}
// Cleanup
[inStream close];
CCCryptorRelease(cryptor);
free(keyPtr);
return ( status == kCCSuccess );
}
Я определенно упускаю здесь что-то очевидное, шифрование и даже использование входных потоков для меня немного в новинку.