8

いくつかのデータが保存されたplistがあり、復号化を暗号化して、ObjectiveCを使用して読み取れないようにしたい。AES暗号化などについて読んだことがありますが、plist内の文字列ではなく、plist全体を暗号化する必要があります。

どんな助けでも本当にありがたいです。

4

3 に答える 3

5

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は、暗号化するplistファイルへのパスを含むNSStringです。
パスワードは、使用する
暗号化キーです。encryptedPathは、暗号化されたファイルを保存する場所です。

復号化するには:

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

暗号化されたパスは、暗号化されたplistファイルへのパスを含むNSStringです。
パスワードは、使用する暗号化キーです
。plistPathは、復号化されたplistファイルを保存する場所です。

于 2012-12-12T17:51:44.883 に答える
3

howanghkが提供するリンクには、バグのあるコードが含まれています。この問題を解決するには、そのWebページにInoriXuが提供する修正を適用します。暗号化機能と復号化機能の両方を変更する必要があります。

したがって、行の後:

const char *password = [pass UTF8String];

追加:

const int passwordLen = [pass length];

そしてラインを変更します:

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

の中へ:

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

コード自体はまだスペースパディングを追加しますが、プロパティリストを暗号化するために必要な場合は、問題ありません。

于 2013-05-08T08:47:42.043 に答える
3

これに対する非常に簡単な答えがあります。これが問題を単純化することを願っています。

まず、ここでNSData+AESファイルをダウンロードする必要があります。必要なのは、NSData+AES.hとNSData+AES.mとcipher.hとcipher.mファイルだけです。保管したら、ファイルをXcodeプロジェクトに追加し、NSData +AES.hおよびcipher.hから#importCocoa/ Cocoa.h>ヘッダーを削除します(iOS向けにプログラミングする場合のみ、MacOS向けにヘッダーを許可してくださいなれ)。plistファイルをフェッチおよび書き込むファイルにNSData+AES.hをインポートします。

最初の基本が設定されたので、これらの重要なファイルの使用法を取り上げます。理解する必要があるのは、データを復号化および暗号化する方法です。最初の実行では、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];
    }

ただし、dataDictionary_が初めて入力されるときは、didFinishLaunchingのAppDelegate.mに強制的に永続化する必要があります。

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

データは常に暗号化されますが、copyPlistメソッドでは、dataDictionary_に関してモデルにデータを入力し、それらのモデルと対話します。完了したら、モデルを永続化して再度暗号化するため、エラーは発生しません。それは簡単で、面倒なことなくかなり実行可能なソリューションです。乾杯。

于 2014-08-30T11:37:54.793 に答える