我有一个带有一些存储数据的plist并且想加密解密因此使用目标c无法读取。我已经读过关于AES加密等但我想要整个plist加密一些如何不是plist中的字符串....
任何帮助都会非常感激。
答案 0 :(得分: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 是一个NSString,包含要加密的plist文件的路径
密码是您要使用的加密密钥
encryptedPath 是您要保存加密文件的地方
解密:
NSData *encryptedData = [NSData dataWithContentsOfFile:encryptedPath];
NSData *plistFileData = [plistFileData AESDecryptWithPassphrase:password];
[plistFileData writeToFile:plistPath atomically:YES];
encryptedPath 是一个NSString,包含加密plist文件的路径
密码是您要使用的加密密钥
plistPath 是您要保存解密的plist文件的地方
答案 1 :(得分:3)
这是一个非常简单的答案,希望这可以简化问题,如果有的话;
首先需要下载here的NSData + AES文件。你只需要NSData + AES.h& NSData + AES.m以及cipher.h& cipher.m文件。一旦保管,将文件添加到Xcode项目并删除#import Cocoa / Cocoa.h>来自NSData + AES.h和cipher.h的标题(仅适用于打算为iOS编程的用户,如果是MacOS,请让标题为)。在您获取和编写plist文件的文件中导入NSData + AES.h。
既然已经确定了最初的基础知识,我们就会使用这些重要的文件。您需要了解的是您希望解密和加密数据的方式。在第一次运行时,您需要将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_时,我们必须在didFinishLaunching中强制将它保存在AppDelegate.m中:
DataHandler *dataHandler = [[DataHandler alloc] init];
[dataHandler persistData];
数据将始终加密,但在copyPlist方法中,您将根据dataDictionary_填充模型并与这些模型进行交互。完成后,您将保留模型并再次加密,因此不会发生错误。这很简单,是一个非常可行的解决方案,没有任何麻烦。欢呼声。
答案 2 :(得分:2)
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;
代码本身仍会添加一些空格填充,但如果你需要它来加密属性列表,你会没事的。