Skip to content

Instantly share code, notes, and snippets.

@hisavali
Last active August 29, 2015 14:13
Show Gist options
  • Save hisavali/b15a4a8e875c73458d80 to your computer and use it in GitHub Desktop.
Save hisavali/b15a4a8e875c73458d80 to your computer and use it in GitHub Desktop.
NString comparsions operators -- CONTAINS/LIKE -- it doesn't work on NSData
Problem: Once encrypted values are stored as NSData in persistent store, if fetch takes place with NSPredicate which uses string (not basic) comparisons operators -- CONTAINS/LIKE -- it doesn't work for NSData.
Note: I have to stop having random values for 'iv' & 'salt' generationed in DataGenerator.m
Please find my code in files listed below. I have provided comments against working & non-working code.
Question: In order to fetch data, how to form sql query (predicate) with string operators 'like, contains or match' for encrypted data.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSManagedObjectContext *context = [self managedObjectContext];
// Create new core data object
NSManagedObject *coreDataObject = [NSEntityDescription insertNewObjectForEntityForName:@"CoreDataObject" inManagedObjectContext:context];
NSString * value = @"Hello world";
// Set our encrypted attribute
[coreDataObject setValue:value forKey:@"encrypted_field"];
// Save our object
NSError *error = nil;
if (![context save:&error]) {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
// Fetch the Object back from core data
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"CoreDataObject" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
// Works as expected: In NSPredicate, basic Comparisons operators works. See http://nshipster.com/nspredicate/ from details for valid basic operators
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"%K == %@", @"encrypted_field", value]];
// Problem: Once encrypted values are stored as NSData in persistent store, if fetch takes place with NSPredicate which
// uses string (not basic) comparisons operators -- CONTAINS/LIKE -- it doesn't work on NSData.
// [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"%K LIKE %@", @"encrypted_field", value]];
// Execute request
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
// Remove items from core CoreDataObject
for (NSManagedObject *info in fetchedObjects) {
[context deleteObject:info];
}
error = nil;
if (![context save:&error]) {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
return YES;
}
@implementation DataGenerator
+ (NSData *)createRandomDataOfLength:(size_t)length {
NSMutableData *data = [NSMutableData dataWithLength:length];
// Stop having random 'Salt' & 'iv' value. As it changes the encryption value (i.e different transformerValue than reverseTransformedValue).
// int result = SecRandomCopyBytes(kSecRandomDefault,
// length,
// data.mutableBytes);
// NSAssert(result == 0, @"Unable to generate random bytes: %d",
// errno);
return data;
}
@smit9612
Copy link

Did you get this working? I am also stuck with similar issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment