Шифровать / расшифровывать.plist файл ios
У меня есть plist с некоторыми сохраненными данными и хочу зашифровать дешифрование, чтобы он не читался с помощью objective c. я читал о шифровании AES и т. д., Но я хочу, чтобы весь plist был зашифрован, как не строки в plist....
любая помощь будет действительно оценили.
3 ответов
ссылка, предоставленная howanghk, содержит код с ошибкой. Примените исправление, предоставленное InoriXu на этой веб-странице, чтобы решить проблему. Необходимо изменить функции шифрования и дешифрования.
после строки:
const char *password = [pass UTF8String];
добавить:
const int passwordLen = [pass length];
и измените строку:
key[i] = password != 0 ? *password++ : 0;
в:
key[i] = i < passwordLen != 0 ? *password++ : 0;
сам код по-прежнему добавляет некоторое пространство, но если вам нужно зашифровать список свойств, вы будете в порядке.
используя код на http://blog.objectgraph.com/index.php/2010/04/20/encrypting-decrypting-base64-encode-decode-in-iphone-objective-c/ (ссылка, которую вы предоставили в комментарии), Вы можете зашифровать свой plist:
NSData *plistFileData = [NSData dataWithContentsOfFile:plistPath];
NSData *encryptedData = [plistFileData AESEncryptWithPassphrase:password];
[encryptedData writeToFile:encryptedPath atomically:YES];
plistPath - это NSString, содержащий путь к файлу plist, который вы хотите зашифровать
пароль это ключ шифрования, который вы хотели бы использовать
encryptedPath где вы хотите сохранить зашифрованный файл
расшифровать:
NSData *encryptedData = [NSData dataWithContentsOfFile:encryptedPath];
NSData *plistFileData = [plistFileData AESDecryptWithPassphrase:password];
[plistFileData writeToFile:plistPath atomically:YES];
encryptedPath - это NSString, содержащая путь к зашифрованному файлу plist
пароль это ключ шифрования, который вы хотели бы использовать
plistPath где вы хотите сохранить расшифрованный файл plist файл
вот очень простой ответ на это, надеюсь, что это упрощает проблему, если таковые имеются;
сначала вам нужно загрузить файлы NSData+AES для здесь. Вам просто нужны NSData+AES.h & NSData+AES.м вместе с шифром.H и шифр.m-файл. После задержания добавьте файлы в проект Xcode и удалите #import Cocoa / Cocoa.H > заголовок из NSData+AES.H и шифр.h (только для тех, кто намерен программировать для iOS, если для MacOS, пожалуйста, оставьте заголовок). Импорт NSData+AES.ч в вашем файле, где вы получаете и пишете файл plist.
теперь, когда начальные основы были заложены, мы берем на себя использование этих важных файлов. Что вам нужно понять, так это то, как вы хотите расшифровать и зашифровать свои данные. При первом запуске вам нужно скопировать нужные файлы в папку документы, а затем зашифровать его. Обратите внимание, если вы скопируете его и попытаетесь расшифровать его прямо, он бросит и исключение, поэтому для этого мы будем использовать логическое значение UserDefaults и пропустим расшифровка при первом запуске. Также вам нужно определить строку константы директивы препроцессора для развлечения секретного ключа для шифрования и дешифрования. Вот что вы будете иметь в своем классе DataHandler;
#import <Foundation/Foundation.h>
#import "NSData+AES.h"
#define MY_SECRET_KEY @"MY_SECRET_KEY"
static NSMutableDictionary *dataDictionary_ = nil;
static NSMutableDictionary *allSettings_ = nil;
@implementation DataHandler
- (id)init
{
if(self = [super init])
{
[self copyPlistData];
}
return self;
}
// Encrypt File
- (NSData*)encryptFile:(NSMutableDictionary *)plistDict
{
NSError *err = nil;
NSData *data = [NSPropertyListSerialization dataWithPropertyList:plistDict format:NSPropertyListXMLFormat_v1_0 options:0 error:&err];
NSData *file = [data encryptWithString:MY_SECRET_KEY];
return file;
}
// Decrypt File
- (NSMutableDictionary *)decryptFile:(NSData *)data
{
NSError *err = nil;
NSData* newData = [data decryptWithString:MY_SECRET_KEY];
NSPropertyListFormat format;
NSMutableDictionary *file = [NSPropertyListSerialization propertyListWithData:newData options:NSPropertyListMutableContainersAndLeaves format:&format error:&err];
return file;
}
- (void) copyPlistData
{
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent: @"myData.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL fileExists = [fileManager fileExistsAtPath:path];
//check if the file exists already in users documents folder
//if file does not exist copy it from the APPLICATION bundle Plist file
if (!fileExists)
{
NSLog(@"copying database to users documents");
NSString *pathToSettingsInBundle = [[NSBundle mainBundle] pathForResource:@"mydata" ofType:@"plist"];
BOOL copySuccess = [fileManager copyItemAtPath:pathToSettingsInBundle toPath:path error:&error];
if(copySuccess)
{
noCopyError_ = YES;
}
}
//if file is already there do nothing
else
{
noCopyError_ = YES;
NSLog(@"users database already configured");
}
BOOL firstRun = [[NSUserDefaults standardUserDefaults] boolForKey:@"IS_FIRST_RUN"];
if(noCopyError_ && firstRun)
{
dataDictionary_ = [self decryptFile:[NSData dataWithContentsOfFile:path]];
}
else
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"IS_FIRST_RUN"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *plistPath = [documentsDirectory stringByAppendingPathComponent:@"mydata.plist"];
dataDictionary_ = (NSMutableDictionary*)[[NSDictionary alloc ] initWithContentsOfFile:plistPath];
NSMutableDictionary *data = (NSMutableDictionary*)[dictionaryDATA_ objectForKey:@"Data"];
allSettings_ = [data objectForKey:@"AllSettings"];
}
}
- (NSMutableDictionary*) properties
{
NSMutableDictionary * props = [[NSMutableDictionary alloc]init];
[props setObject: allSettings_ forKey:@"AllSettings"];
NSMutableDictionary * data = [NSMutableDictionary dictionaryWithObject:props forKey:@"Data"];
return data;
}
- (void)persistData
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *plistPath = [documentsDirectory stringByAppendingPathComponent:@"mydata.plist"];
NSMutableDictionary *dict = [self properties];
NSData *encryptedDict = [self encryptFile:dict];
[encryptedDict writeToFile:plistPath atomically:YES];
}
но при первом заполнении dataDictionary_ мы должны принудительно сохранить его в AppDelegate.m в didFinishLaunching:
DataHandler *dataHandler = [[DataHandler alloc] init];
[dataHandler persistData];
данные всегда будут зашифрованы в любое время, но в методе copyPlist вы будете заполнять свои модели уважайте dataDictionary_ и взаимодействуйте с этими моделями. Когда это будет сделано, вы будете сохранять свои модели и шифровать снова, следовательно, никаких ошибок не произойдет. Это простое и довольно работоспособное решение без каких-либо хлопот. Овации.