I have a live iOS application on apple app-store which is using the core data.
Now I want to encrypt the core-data using EncryptedCoreData (https://github.com/project-imas/encrypted-core-data 2).
I am successfully able to implement the same with my project and it working fine for fresh installed but when I tried to override my existing application which is not using the encrypted coredata with the new application which is using the encrypted coredata at that time I am unable to get my old data back.
I don't know what I am doing wrong.
Following is my code sample
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (persistentStoreCoordinator_ != nil) {
return persistentStoreCoordinator_;
}
else if (!storeUrl)
return nil;
NSError *error = nil;
persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
NSDictionary *options = @{ EncryptedStorePassphraseKey : @"123456",
EncryptedStoreFileManagerOption : [EncryptedStoreFileManager defaultManager],
NSMigratePersistentStoresAutomaticallyOption : @YES
};
NSPersistentStore *store = [persistentStoreCoordinator_
addPersistentStoreWithType:EncryptedStoreType
configuration:nil
URL:storeUrl
options:options
error:&error];
if (!store && error)
{
[self encryptDB:[storeUrl absoluteString] url:storeUrl];
NSError *error1 = nil;
NSPersistentStore *store1 = [persistentStoreCoordinator_
addPersistentStoreWithType:EncryptedStoreType
configuration:nil
URL:storeUrl
options:options
error:&error1];
}
return persistentStoreCoordinator_;
}
//encryptDB used for encriptt the existing DB with password
- (void)encryptDB:(NSString*)path_u url:(NSURL*)url
{
sqlite3 *unencrypted_DB;
sqlite3 *encrypted_DB;
NSString *tempFile = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
stringByAppendingPathComponent:@"encrypted.sqlite"];
NSURL *tempUrl = [NSURL fileURLWithPath:tempFile];
if (sqlite3_open([path_u UTF8String], &unencrypted_DB) == SQLITE_OK) {
NSLog(@"Database Opened");
// Attach empty encrypted database to unencrypted database
NSString *strEncryptedPath = [NSString stringWithFormat:@"ATTACH DATABASE '%@' AS encrypted KEY '123456';",tempFile];
sqlite3_exec(unencrypted_DB, [strEncryptedPath UTF8String], NULL, NULL, NULL);
// export database
sqlite3_exec(unencrypted_DB, "SELECT sqlcipher_export('encrypted');", NULL, NULL, NULL);
// Detach encrypted database
sqlite3_exec(unencrypted_DB, "DETACH DATABASE encrypted;", NULL, NULL, NULL);
int version = [self queryUserVersion:unencrypted_DB];
sqlite3_close(unencrypted_DB);
NSLog (@"End database copying");
if (sqlite3_open([tempFile UTF8String], &encrypted_DB) == SQLITE_OK) {
const char* key = [@"123456" UTF8String];
sqlite3_key(encrypted_DB, key, (int)strlen(key));
[self setVersion:encrypted_DB version:(int)version];
}
sqlite3_close(encrypted_DB);
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtURL:url error:&error];
BOOL result = [[NSFileManager defaultManager] moveItemAtURL:tempUrl toURL:url error:&error];
if(!result)
NSLog(@"Error: %@", error);
}
else {
sqlite3_close(unencrypted_DB);
//NSAssert1(NO, @"Failed to open database with message '%s'.", sqlite3_errmsg(unencrypted_DB));
}
}
-(void)setVersion: (sqlite3*) db version:(int)version {
// get current database version of schema
static sqlite3_stmt *stmt_version;
if(sqlite3_prepare_v2(db, "PRAGMA user_version;", -1, &stmt_version, NULL) == SQLITE_OK) {
while(sqlite3_step(stmt_version) == SQLITE_ROW) {
db = sqlite3_bind_int( stmt_version, 1, version ); // Bind first parameter.
}
} else {
NSLog(@"%s: ERROR Preparing: , %s", __FUNCTION__, sqlite3_errmsg(db) );
}
sqlite3_finalize(stmt_version);
}
-(int)queryUserVersion: (sqlite3*) db {
// get current database version of schema
static sqlite3_stmt *stmt_version;
int databaseVersion;
if(sqlite3_prepare_v2(db, "PRAGMA user_version;", -1, &stmt_version, NULL) == SQLITE_OK) {
while(sqlite3_step(stmt_version) == SQLITE_ROW) {
databaseVersion = sqlite3_column_int(stmt_version, 0);
NSLog(@"%s: version %d", __FUNCTION__, databaseVersion);
}
NSLog(@"%s: the databaseVersion is: %d", __FUNCTION__, databaseVersion);
} else {
NSLog(@"%s: ERROR Preparing: , %s", __FUNCTION__, sqlite3_errmsg(db) );
}
sqlite3_finalize(stmt_version);
return databaseVersion;
}
Following code I am using for fetch the data
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"HistoryEvent" inManagedObjectContext:dbDataFile.managedObjectContext];
[request setEntity:entity];
NSMutableArray* andPredicateArray = [[NSMutableArray alloc] init];
if (guid)
{
[andPredicateArray addObject:
[NSPredicate predicateWithFormat:@"guid = %@", guid]];
}
NSPredicate* predicate = [NSCompoundPredicate andPredicateWithSubpredicates:andPredicateArray];
[request setPredicate:predicate];
[request setFetchLimit:limit];
NSMutableArray* sortDescriptors = [[NSMutableArray alloc] init];
[sortDescriptors addObject:
[[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:[isAscendingCreationDatesNum boolValue]]];
[request setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[dbDataFile.managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (!mutableFetchResults && errorMessage && error)
{
NSLog(@"Error to fetch”); //I am not getting any error here
}
return mutableFetchResults; //Count is zero
Can anyone please help me and point out what I am doing wrong.
Again If I installed fresh application then the same code is working fine
I am only getting empty data when tried to override the existing app i.e installing encrypted coredata app on non-encrypted coredata.
I also created an issue at https://discuss.zetetic.net/t/unable-to-fetch-data/4560
I have a live iOS application on apple app-store which is using the core data. Now I want to encrypt the core-data using EncryptedCoreData (https://github.com/project-imas/encrypted-core-data 2). I am successfully able to implement the same with my project and it working fine for fresh installed but when I tried to override my existing application which is not using the encrypted coredata with the new application which is using the encrypted coredata at that time I am unable to get my old data back. I don't know what I am doing wrong. Following is my code sample
Following code I am using for fetch the data
Can anyone please help me and point out what I am doing wrong. Again If I installed fresh application then the same code is working fine I am only getting empty data when tried to override the existing app i.e installing encrypted coredata app on non-encrypted coredata. I also created an issue at https://discuss.zetetic.net/t/unable-to-fetch-data/4560