Ios 加密/解密.plist文件

Ios 加密/解密.plist文件,ios,encryption,plist,Ios,Encryption,Plist,我有一个包含一些存储数据的plist,希望对其进行加密和解密,因此使用objective c无法读取。我读过AES加密等,但我想对整个plist进行加密,而不是plist中的字符串 非常感谢您的帮助。使用(您在评论中提供的链接)上的代码,您可以通过以下方式加密plist: NSData *plistFileData = [NSData dataWithContentsOfFile:plistPath]; NSData *encryptedData = [plistFileData AESEncr

我有一个包含一些存储数据的plist,希望对其进行加密和解密,因此使用objective c无法读取。我读过AES加密等,但我想对整个plist进行加密,而不是plist中的字符串

非常感谢您的帮助。

使用(您在评论中提供的链接)上的代码,您可以通过以下方式加密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文件的位置。howanghk提供的链接包含有bug的代码。在该网页上应用InoriXu提供的修复程序以解决问题。您必须同时修改加密和解密函数

所以在一行之后:

const char *password = [pass UTF8String];
加:

换乘路线:

key[i] = password != 0 ? *password++ : 0;
进入:

key[i]=i

代码本身仍然在后面添加了一些空格填充,但是如果您需要它来加密属性列表,就可以了。

这里有一个非常简单的答案,希望这可以简化问题(如果有)

首先,您需要下载NSData+AES文件。您只需要NSData+AES.h&NSData+AES.m以及cipher.h&cipher.m文件。保管后,将文件添加到您的Xcode项目中,并从NSData+AES.h和cipher.h中删除#import cococoa/Cocoa.h>标题(仅适用于打算为iOS编程的用户,如果是为MacOS编程,请保留标题)。在文件中导入NSData+AES.h,从中获取和写入plist文件

既然已经奠定了最初的基础,我们就开始使用这些重要文件。您需要了解的是,您想要解密和加密数据的方式。在第一次运行时,您需要将plist复制到documents文件夹,然后对其进行加密。注意,如果您复制它并尝试直接解密它,它将抛出和异常,因此为了满足这一点,我们将使用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];
    }

数据将始终加密,但在copyPlist方法中,您将根据dataDictionary填充模型,并与这些模型交互。完成后,您将持久化模型并再次加密,因此不会发生错误。这是一个简单而可行的解决方案,没有任何麻烦。干杯。

我已经尝试过了,并将文件二进制化,如果密码存储在应用程序中(例如,作为字符串)为true,则可以检索密码,但是这应该足以阻止临时用户阅读/修改plist文件。链接不是我提供的,而是由用户14356(op)提供的在问题的评论中,您忘了解释IOS开发人员在删除35; import Cocoa/Cocoa.h>标题时需要添加#import
key[i] = i < passwordLen != 0 ? *password++ : 0;
    #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];
    }
    DataHandler *dataHandler = [[DataHandler alloc] init];
    [dataHandler persistData];