How can I encrypt CoreData contents on an iPhone

IphoneEncryptionCore Data

Iphone Problem Overview


I have some information I'd like to store statically encrypted on an iPhone application. I'm new to iPhone development, some I'm not terribly familiar with CoreData and how it integrates with the views. I have the data as JSON, though I can easily put it into a SQLITE3 database or any other backing data format. I'll take whatever is easiest (a) to encrypt and (b) to integrate with the iPhone view layer.

The user will need to enter the password to decrypt the data each time the app is launched. The purpose of the encryption is to keep the data from being accessible if the user loses the phone.

For speed reasons, I would prefer to encrypt and decrypt the entire file at once rather than encrypting each individual field in each row of the database.

Note: this isn't the same idea as Question 929744, in which the purpose is to keep the user from messing with or seeing the data. The data should be perfectly transparent when in use.

Also note: I'm willing to use SQLCipher to store the data, but would prefer to use things that already exist on the iPhone/CoreData framework rather than go through the lengthy build/integration process involved.

Iphone Solutions


Solution 1 - Iphone

You can encrypt individual properties in your Core Data model entities by making them transformable properties, then creating an NSValueTransformer subclass which will encrypt and decrypt the data for that property. While this is not the whole-database decryption that you're looking for, it will have a much lower memory footprint than decrypting an entire database into memory. Additionally, it will allow the decryption to be done lazily, rather than all up front, so your application will load much faster. Depending on the encryption used, I would even expect that the on-disk data accesses for loading each entity would be slower than the decryption process for the properties, so you won't see that much of a performance penalty when accessing the properties.

Transformable properties like this are very easy to use, because you read and write to them as normal, while the encryption / decryption goes on behind the scenes.

Solution 2 - Iphone

Do you need to encrypt? Newer iPhones (3Gs, 4, iPad...) encrypt all data on the device. With a single, hashed, salted password on your app, no one can get to the data without a password. Data is sandboxed from all other apps.

https://stackoverflow.com/questions/4958362/data-protection-on-ios

Solution 3 - Iphone

"The purpose of the encryption is to keep the data from being accessible if the user loses the phone."

iOS has had Data Protection since iOS 4, and Core Data has supported this for a long time. Data protection is designed for exactly the kinds of scenarios you are interested in. By default, Core Data NSSQLiteStoreType files have NSFileProtectionCompleteUntilFirstUserAuthentication for applications built with the iOS 5 API or later. The WWDC 2012 session Protecting the User's Data goes into this topic in much more detail, and recommends using NSFileProtectionComplete. You can use this with Core Data by passing that value in the options dictionary used to open your Core Data NSSQLiteStoreType store.

Example:

NSDictionary *storeOptions = @{ NSPersistentStoreFileProtectionKey : NSFileProtectionComplete };
if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self storeURL] options:storeOptions error:&error]){

The broader topic of device security is covered in iOS Device Security

Solution 4 - Iphone

I am currently using https://github.com/project-imas/encrypted-core-data to encrypt my coredata store. It is a custom implementation of NSIncrementalStore basically is a community replacement for apple's own persistent store that has an encryption option. It is a drop-in solution that works. You can also take the sqlite file out and decrypt it with whatever passcode you choose in many different clients.

The implementation does not have 100% coverage and doesn't allow for some features such as subquery predicates. I am due to submit my first PR to the repo to hope change that soon ;-). I almost have it completley working with a very complex coredata app. It also has the added benefit of allowing you direct SQLite access without having to worry about apple's implementation changing on you since you have full access to the source.

Solution 5 - Iphone

I succeeded in adapting Apple's CustomAtomicStoreSubclass example code for use in a Mac desktop application, resulting in an encrypted NSBinaryStore-style persistent store written as a single file in the filesystem. My approach:

  • Copy the CustomAtomicStoreSubclass & CustomAtomicStoreSubclassCacheNode class source code into my project and rename them
  • Store the key and initial vector in the Keychain
  • Use the OpenSSL library bundled with Mac OS X
  • Encrypt NSKeyedArchiver output and write the ciphertext to disc (decryption is the reverse)

I intercepted backing store reads & writes in the readFile, metadataForPersistentStoreWithURL:error:, setMetadata:forPersistentStoreWithURL:error:, and save: methods in CustomAtomicStoreSubclass.

The Subclassing Notes for the iPhone's NSAtomicStore Class Reference looks similar to that of Mac OS X's. Perhaps this approach might also work with the iPhone.

Solution 6 - Iphone

I know this is an old question, but it's still quite relevant and I recently had to tackle the subject myself.

Transformable properties are a potential solution, but did not seem to work with NSPredicates, which is a big drawback. I did not pursue the CustomAtomicStoreSubclass approach, but am curious if others have had success with it.

My concerns were similar to those of the original poster, and I ultimately wound up doing the following:

  1. Decrypt the store to a temp file
  2. Load the decrypted store normally
  3. Migrate the store to an in-memory store
  4. Delete the unencrypted store

In my case, my store was read-only, but this could be expanded to write the store back out, encrypt it, and delete the unencrypted store once more. You can also always skip #3 if you have a large store and/or aren't concerned about having an unencrypted file sitting around while your app is running.

The Core Data file I was working with was ~1MB, and could be encrypted/decrypted very quickly.

Solution 7 - Iphone

How do I encrypt or decrypt data?

"The Certificate, Key, and Trust Services API provides functions for generating symmetric and asymmetric encryption keys, creating and verifying digital signatures, and encrypting keys and nonces. The CommonCrypto library is used for symmetric encryption, hashing, and HMAC operations. Refer to Certificate, Key, and Trust Services Reference and the CC_crypto(3cc) man pages for for more information."

Solution 8 - Iphone

You can use Trasformables, and I confirm, you cannot use them with predicates, but (and it's worse) you cannot even use

... = [self primitiveValueForKey:@"crypted_data"];

if You use predicates..

it works fine if You crypt you data using:

[self setPrimitiveValue:cryptedPsw forKey:@"crypted_data"];

to crypt data. (and for example on the simulator.... and move on the project bundle later..)

Solution 9 - Iphone

Encryption is encryption no matter what format your data is in, and you certainly don't need to worry about how anything "integrates with the views." All you have to do is decrypt it before you try to read anything meaningful.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJames A. RosenView Question on Stackoverflow
Solution 1 - IphoneBrad LarsonView Answer on Stackoverflow
Solution 2 - IphoneTom AndersenView Answer on Stackoverflow
Solution 3 - IphonequellishView Answer on Stackoverflow
Solution 4 - IphonetslaterView Answer on Stackoverflow
Solution 5 - IphoneTy.View Answer on Stackoverflow
Solution 6 - IphoneCruttView Answer on Stackoverflow
Solution 7 - IphoneAlex ReynoldsView Answer on Stackoverflow
Solution 8 - IphoneingcontiView Answer on Stackoverflow
Solution 9 - IphoneAzeem.ButtView Answer on Stackoverflow