Шифроване/декриптиране на .plist файл ios

имам plist с някои съхранени данни и искам да дешифрирам, така че да не може да се чете с помощта на обектив c. Четох за AES криптиране и т.н., но искам целият plist да бъде криптиран, по някакъв начин не низовете в plist....

всяка помощ ще бъде наистина оценена.


person fizampou    schedule 12.12.2012    source източник
comment
Опитах това blog.objectgraph.com/index.php/2010/04/20/ и правене на файла двоичен   -  person fizampou    schedule 12.12.2012


Отговори (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;

Самият код все още добавя малко пространство отзад, но ако имате нужда от него, за да шифровате списък със свойства, ще се оправите.

person frin    schedule 08.05.2013
comment
връзката не беше предоставена от мен, тя беше предоставена от user14356 (операторът) в коментара на въпроса. - person howanghk; 17.05.2013

Използване на кода на https://web.archive.org/web/20150612123348/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< /em> е мястото, където искате да запишете шифрования файл

за дешифриране:

NSData *encryptedData = [NSData dataWithContentsOfFile:encryptedPath];
NSData *plistFileData = [plistFileData AESDecryptWithPassphrase:password];
[plistFileData writeToFile:plistPath atomically:YES];

encryptedPath е NSString, съдържащ пътя до шифрования plist файл
парола е ключът за шифроване, който искате да използвате
plistPath е мястото, където искате да запишете дешифрирания plist файл

person howanghk    schedule 12.12.2012
comment
fyi, възможно е да извлечете паролата, ако е съхранена в приложението (т.е. като низ например) - person drct; 08.05.2013
comment
вярно, но това трябва да е достатъчно, за да попречи на случайните потребители да четат / модифицират plist файла. - person howanghk; 08.05.2013

Ето един много прост отговор на това, надявам се това да опрости проблема, ако има такъв;

Първо трябва да изтеглите NSData+AES файловете за тук . Просто се нуждаете от NSData+AES.h & NSData+AES.m заедно с файловете cipher.h & cipher.m. След като сте в ареста, добавете файловете към вашия Xcode проект и премахнете заглавката #import Cocoa/Cocoa.h> от NSData+AES.h и cipher.h (само за тези, които възнамеряват да програмират за iOS, ако за MacOS, моля, оставете заглавката бъда). Импортирайте NSData+AES.h във вашия файл, където извличате и записвате вашия plist файл.

Сега, след като първоначалните основи са положени, ние поемаме използването на тези важни файлове. Това, което трябва да разберете, е начинът, по който искате да дешифрирате и шифровате вашите данни. При първото стартиране трябва да копирате своя 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_ и ще взаимодействате с тези модели. Когато сте готови, ще запазите своите модели и ще шифровате отново, така че няма да възникнат грешки. Това е просто и доста работещо решение без никакви проблеми. наздраве

person Mohsin Khubaib Ahmed    schedule 30.08.2014
comment
Забравяте да обясните, че разработчиците на IOS трябва да добавят #import ‹Foundation/Foundation.h›, когато премахват #import Cocoa/Cocoa.h› хедър - person Aitul; 09.02.2015