2012-12-12 73 views
7

我有一个plist与一些存储的数据,并希望加密解密,因此它是不可读的使用目标c。我读过关于AES加密等,但我希望整个plist加密一些怎么不在plist中的字符串....加密/解密.plist文件ios

任何帮助将非常感激。

+0

我已经尝试http://blog.objectgraph.com/index.php/2010/04/20/encrypting-decrypting-base64-encode-decode-in-iphone-objective-c/并将文件二进制文件 – zaabalonso

回答

2

howanghk提供的链接包含co德有一个错误。在该网页上应用InoriXu提供的修补程序来解决问题。您必须修改加密和解密函数。一个行后那么

const char *password = [pass UTF8String]; 

地址:

const int passwordLen = [pass length]; 

而且变线:

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

到:

key[i] = i < passwordLen != 0 ? *password++ : 0; 

代码本身仍然在后面添加一些空格填充,但如果您需要它来加密属性列表,那么您将会很好。

+0

该链接并非由我提供,而是由用户14356(op)在该问题的评论中提供的。 – howanghk

4

使用代码在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是包含路径要加密的plist文件的NSString
密码是加密密钥,你想用
encryptedPath是要保存加密文件

解密:

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

encryptedPath是一个包含对加密的plist文件
密码是你想使用的加密密钥的路径的NSString
plistPath是你想要保存解密后的plist文件

+0

这就是我做的,但plist解密后不可读.... – zaabalonso

+0

fyi,如果它存储在应用程序(如作为一个字符串例如) – drct

+1

真的,它可能会检索密码,但是这应该足以停止临时用户阅读/修改plist文件。 – howanghk

3

这是一个非常简单的答案,希望这可以简化问题,如果有的话;

首先你需要为here下载NSData + AES文件。您只需要NSData + AES.h & NSData + AES.m以及cipher.h & cipher.m文件。一旦羁押,将这些文件添加到您的Xcode项目中,并从NSData + AES.h和cipher.h中删除#import Cocoa/Cocoa.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:

​​

的数据将始终在所有时间,但在copyPlist加密方法,您将针对dataDictionary_填充模型并与这些模型进行交互。完成后,您将坚持模型并再次加密,因此不会发生错误。这很简单,而且没有任何麻烦。干杯。

+0

你忘记解释IOS开发者在删除#import Cocoa/Cocoa.h头时需要添加#import Aitul