Сохранение зашифрованного текста uint8_t в DataModel

Я создаю простое приложение для iphone (SDK6.1), которое шифрует заметки некоторых пользователей, сохраняет их в базе данных, и когда пользователь вводит пароль (его не нужно шифровать), он расшифровывает свои заметки и показывает их ему.

Для базы данных я использую Core Data (.xcdatamodel). Зашифрованный текст в настоящий момент объявляется как String в модели данных, а в файле Notes.h - как NSString.

Для Шифрования я использую пример кода Apple от CryptoExercise, который работает отлично.

Проблема в том, что когда я пытаюсь сохранить зашифрованный текст в базе данных, а затем расшифровать его, я не получаю желаемых результатов... в основном я получаю пустую строку обратно.

Очевидно, я использую следующий код для преобразования из uint8_t в NSString, чтобы я мог сохранить его в модель данных, и я понимаю, что это моя главная проблема.

uint8_t *cipherBuffer = NULL;
SecKey *encrypt = [[SecKey alloc]init];
NSString *et = [[NSString alloc]init];

[encrypt generateKeyPairRSA];

// Encrypt the plain text
cipherBuffer = [encrypt Encryption:plainTextField.text];

// Convert uint8_t to NSString
NSMutableData *data = [[NSMutableData alloc]init];
[data appendBytes:cipherBuffer length:strlen((char*)cipherBuffer)+1];
NSString *string = [[NSString alloc]initWithData:data encoding: NSASCIIStringEncoding];

// Save to Data Model
[self.currentNote setEncryptedText:string];
[self.delegate addNewNoteViewControllerDidSave];
// Retrieve encrypted text from database
et = [self.currentNote encryptedText];

// Convert back to uint_8
NSData *someData = [et dataUsingEncoding:NSUTF8StringEncoding];
const void *bytes = [someData bytes];
uint8_t *crypto_data = (uint8_t*)bytes;

// Decrypt Data
[encrypt Decryption:crypto_data];

Как я уже говорил, я понимаю, что преобразование uint8_t является главной проблемой здесь, и я хотел бы знать, какой правильный способ сделать это?

Это возможно с моделью данных вообще, или я должен перейти на SQLite?

2 ответа

Решение

Так что просто чтобы ответить на вопрос, чтобы я мог использовать код и все...

Я изменил EncryptedText в модели данных на двоичные данные, и тогда код будет выглядеть так:

uint8_t *cipherBuffer = NULL;
SecKey *encrypt = [[SecKey alloc]init];

[encrypt generateKeyPairRSA];

cipherBuffer = [encrypt Encryption:plainTextField.text];

NSMutableData *data = [[NSMutableData alloc]init];
[data appendBytes:cipherBuffer length:strlen((char*)cipherBuffer)+1];

// Save cipher into the Data Model
[self.currentNote setEncryptedText:data];
[self.delegate addNewNoteViewControllerDidSave];

// Retrieve cipher back from Data Model
NSData *etData = [[NSData alloc]init];
etData = [self.currentNote encryptedText];

// Convert back to uint8_t
const void *bytes = [etData bytes];
uint8_t *crypto_data = (uint8_t*)bytes;

// De cypher
[encrypt Decryption:crypto_data];

Вы не можете конвертировать произвольные байтовые последовательности в NSString и обратно так. Например, если data содержит один байт 128 (шест 0x80), затем

NSString *string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];

создает строку с одним символом Unicode U+0080. Когда вы конвертируете это обратно в NSData с

NSData *d1 = [string dataUsingEncoding:NSUTF8StringEncoding];

затем d1 будет содержать байты 0xC2 0x80 (который является UTF-8 для U+0080). Но

NSData *d2 = [string dataUsingEncoding:NSASCIIStringEncoding];

тоже не работает (d2 = nil), потому что строка не может быть преобразована в 7-битный ASCII.

Так что вы должны либо

  • хранить зашифрованные данные как "двоичные данные" в базовых данных, или
  • сохраните зашифрованные данные как String, но выберите другую стратегию преобразования, например Base64.
Другие вопросы по тегам