2012-12-12 68 views
7

tôi có một plist với một số dữ liệu được lưu trữ và muốn mã hóa giải mã để nó không thể đọc được bằng cách sử dụng mục tiêu c. Tôi đã đọc về mã hóa AES vv nhưng tôi muốn toàn bộ plist được mã hóa một số làm thế nào không dây trong plist ....Mã hóa/giải mã tệp .plist ios

bất kỳ trợ giúp sẽ được thực sự đánh giá cao.

+0

tôi đã thử http://blog.objectgraph.com/index.php/2010/04/20/encrypting-decrypting-base64-encode-decode-in-iphone-objective-c/ và tạo tệp nhị phân – zaabalonso

Trả lời

2

Liên kết được cung cấp bởi howanghk chứa co de với một lỗi. Áp dụng khắc phục do InoriXu cung cấp trên trang web đó để giải quyết vấn đề. Bạn phải sửa đổi cả hai chức năng mã hóa và giải mã.

Vì vậy, sau khi một dòng:

const char *password = [pass UTF8String]; 

add:

const int passwordLen = [pass length]; 

Và sự thay đổi dòng:

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

thành:

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

Bản thân mã vẫn thêm một số khoảng trống phía sau, nhưng nếu bạn cần nó để mã hóa danh sách thuộc tính, bạn sẽ ổn.

+0

liên kết không được cung cấp bởi tôi, nó được cung cấp bởi user14356 (op) trong nhận xét của câu hỏi. – howanghk

4

Sử dụng mã tại http://blog.objectgraph.com/index.php/2010/04/20/encrypting-decrypting-base64-encode-decode-in-iphone-objective-c/ (liên kết mà bạn cung cấp trong bình luận), bạn có thể mã hóa plist của bạn bằng cách:

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

plistPath là một NSString chứa đường dẫn đến tập tin plist bạn muốn mã hóa
mật khẩu là chìa khóa mã hóa mà bạn muốn sử dụng
encryptedPath là nơi bạn muốn lưu các tập tin được mã hóa

để giải mã:

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

encryptedPath là một NSString chứa đường dẫn đến tập tin plist mã hóa
mật khẩu là chìa khóa mã hóa mà bạn muốn sử dụng
plistPath là nơi bạn muốn lưu tệp plist đã được giải mã

+0

thats những gì tôi đã làm nhưng plist là không thể đọc sau khi giải mã .... – zaabalonso

+0

fyi, nó có thể lấy mật khẩu nếu nó được lưu trữ trong ứng dụng (ví dụ như một chuỗi ví dụ) – drct

+1

đúng, tuy nhiên điều này là đủ để ngăn chặn người dùng thông thường đọc/sửa đổi tệp plist. – howanghk

3

Đây là một câu trả lời rất đơn giản cho điều này, hy vọng điều này sẽ đơn giản hóa vấn đề, nếu có;

Trước tiên, bạn cần tải xuống tệp NSData + AES cho here. Bạn chỉ cần NSData + AES.h & NSData + AES.m cùng với các tệp mã hoá .h & cipher.m. Khi bị tạm giữ, hãy thêm các tệp vào dự án Xcode của bạn và xóa tiêu đề #import Cocoa/Cocoa.h> khỏi NSData + AES.h và cipher.h (chỉ dành cho những người có ý định lập trình cho iOS, nếu cho MacOS, vui lòng để tiêu đề được). Nhập NSData + AES.h vào tệp của bạn nơi bạn tìm nạp và viết tệp plist của bạn.

Bây giờ, các khái niệm cơ bản ban đầu đã được đặt ra, chúng tôi sẽ sử dụng các tệp quan trọng này. Điều bạn cần hiểu là cách bạn muốn giải mã và mã hóa dữ liệu của mình.Lúc chạy đầu tiên, bạn cần phải sao chép plist của bạn vào thư mục tài liệu và sau đó mã hóa nó. Lưu ý, nếu bạn sao chép và cố gắng giải mã thẳng nó sẽ ném và ngoại lệ, để phục vụ điều đó, chúng tôi sẽ sử dụng giá trị Boolean UserDefaults và bỏ qua giải mã trong lần chạy đầu tiên. Ngoài ra, bạn cần xác định chuỗi liên tục tiền xử lý để giải mã khóa bí mật để mã hóa và giải mã. Dưới đây là những gì bạn sẽ có trong lớp DataHandler của mình;

#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]; 
    } 

Nhưng lần đầu tiên dataDictionary_ được phổ biến, chúng ta phải buộc ably kiên trì nó trong AppDelegate.m trong didFinishLaunching:

DataHandler *dataHandler = [[DataHandler alloc] init]; 
    [dataHandler persistData]; 

Các dữ liệu sẽ luôn được mã hóa bất cứ lúc nào nhưng trong copyPlist phương pháp bạn sẽ cư trú các mô hình của bạn đối với dataDictionary_ và tương tác với các mô hình đó. Khi thực hiện xong, bạn sẽ tiếp tục duy trì mô hình của mình và mã hóa một lần nữa do đó sẽ không có lỗi nào xảy ra. Nó đơn giản và một giải pháp khá khả thi mà không gặp bất kỳ rắc rối nào. Chúc mừng.

+0

Bạn quên giải thích rằng các nhà phát triển iOS cần thêm #import khi họ xóa #import Cocoa/Cocoa.h> tiêu đề – Aitul