Сохранение зашифрованного текста 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.