0

I have a method that encrypts a peace of string. Method seems to work just fine. My problem is that I don't know how to use it so I can store the data in core data encrypted.

Bellow of my implementation, I have the following lines of code:

#define CC_USERNAME @"myusername"
#define CC_PASSWORD @"mypassrod"
#define CC_SALTED_STRING [NSString stringWithFormat:@"someRandomStringHere%@anDhEreAsWEll", CC_PASSWORD]

Here is the method:

-(void)encryptWebsiteUrl {

    NSData *hash = [NSData sha256forData:CC_SALTED_STRING];
    NSData *iVector = [NSData generateRandomIV:16];

    NSInteger row = [self.websitesTableView selectedRow];
    NSTableColumn *column = [self.websitesTableView tableColumnWithIdentifier:@"websiteUrl"];
    NSCell *cell = [column dataCellForRow:row];
    NSLog(@"cell value:%@", [cell stringValue]);


    NSString *message = [cell stringValue]; // here, I should get the cell value
    NSData *messageData = [message dataUsingEncoding:NSUTF8StringEncoding];

    NSMutableData *encryptedData = [[NSMutableData alloc] initWithData:iVector];

    NSData *payLoad = [NSData encrypt:messageData key:hash iv:iVector];

    [encryptedData appendData:payLoad];
    message = encryptedData;
    NSLog(@"Encrypted message is: %@",message);


    NSData *pureData = [encryptedData subdataWithRange:NSMakeRange(16, [encryptedData length] - 16)];
    NSData *extractedVector = [encryptedData subdataWithRange:NSMakeRange(0, 16)];


    NSData *decryptedData = [NSData decrypt:pureData key:hash iv:extractedVector];

    NSString *decryptedMessage = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
    //NSLog(@"Decrypted message is: %@",decryptedMessage);

}

Right now, I am calling this method like this:

-(void)controlTextDidEndEditing:(NSNotification *)obj {
    [self encryptWebsiteUrl];
}

In the console log, I have the following output:

cell value:www.newone.com Encrypted message is: <474ca213 c80b9135 ae5a31ad f5004006 556de1db 6835cad2 aa408084 442a8a1f>

In the encryption method, I use self.websitesTableView. That is the table view with one column only in which I store my data, and the column is named websiteUrl (see the code in the method)

My question is: how can I use this method to store encrypted value of the websiteUrl in core data which is now stored unencrypted.

I want to mention here 2 things. One, in core data, attribute websiteUrl is transformable, and second, I use binding, which is the reason why I didn't post any code related with saving or inserting data in the websitesTableView.

7
  • Can you use a value converter in the binding? Commented Apr 7, 2016 at 12:22
  • I have no idea how to do that. Commented Apr 7, 2016 at 12:26
  • If you use bindings, use arraycontroller.selectedObjects instead of tableview.selectedRow to get the data. Commented Apr 7, 2016 at 12:28
  • Sorry, I mean value transformer. Look up NSValueTransformer. Commented Apr 7, 2016 at 12:30
  • A formatter (NSFormatter) could also do the trick. Commented Apr 7, 2016 at 12:33

2 Answers 2

1

Yes you can store binary data in Core Data. The contents of that binary data is irrelevant to Core Data. Therefore, yes, you can store encrypted data in Core Data.

However, you might want to consider two other options:

  1. Storing things like this in the keychain. That is what it is designed for.
  2. Turning on file level encryption for Core Data so that the encryption is transparent to you and your application.

If you want to store encrypted data, configure the attribute of the entity to be binary data. Then you just get and set NSData to that property. You can even add convenience methods to the subclass so that everything outside of the subclassed NSManagedObject will only access the unencrypted data.

Update 1

You add the NSPersistentStoreFileProtectionKey key to the options when you add the NSPersistentStore to the NSPersistentStoreCoordinator.

let options:[String:AnyObject] = [NSPersistentStoreFileProtectionKey: NSFileProtectionComplete]

Then pass those options into the addPersistentStoreWithType....

There are several options for the encryption experience you are looking for.

Sign up to request clarification or add additional context in comments.

5 Comments

My attribute in coredata named websiteUrl is transformable. Having the above code (in my question), can you please post some code snipped?
How do I turn on file level encryption for Core Data?
Is file level encryption for Core Data available on OS X?
@user2417624 Code for what? I presented a couple of options plus the other answer sent you to an answer with code. How much more code do you need and on what subject?
@Willeke No, per the documentation it is iOS only.
0

Solution 1. Use a value transformer in the data model. NSValueTranformer to encrypt data

Solution 2. Use a value transformer in the binding. This is the same value transformer as solution 1.

Solution 3. Do encryption and decryption in custom accessors.

Solution 4. Use an encrypted and decrypted property.

2 Comments

You really do not need a value transformer if you are going to write custom accessors. The data is accessible directly from the NSManagedObject as NSData and it is the same trip from there to unencrypted data.
Pick one, not two, of the four solutions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.