How can I encrypt CoreData contents on an iPhone - iphone

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.

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.

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.
Data Protection on iOS

"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

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.

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.

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:
Decrypt the store to a temp file
Load the decrypted store normally
Migrate the store to an in-memory store
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.

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."

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..)

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.

Related

What is un-secure about NSUserDefaults, is manual encryption safe?

If I understand correctly: NSUserDefaults is an un-secure place to store sensitive data because some settings file can be hacked and the NSUserDefault values can be changed.
What exactly can be hacked and not hacked? Can the Hacker see my app's Swift Code, or do they only see the list of variables and values stored in NSUserDefaults?
Could I create my own "encryption" in my code (where the NSUserDefault values appear like a bunch of meaningless numbers, and the "key" is inside my code with some convoluted mathematical operation to do)? Is this safe?
Note: I don't intend on encrypting anything serious like usernames or passwords, just Highscores and Bool values for whether or not levels/upgrades are unlocked. I don't want to have to learn KeychainsWrappers if my manual solution is safe.
Side-question (though I haven't reached this step yet): How are in-app purchases handled? is there a Bool value that says whether or not an item was paid for, and where is that Bool stored (is it up to you to decide)?
What exactly can be hacked and not hacked?
Most everything you can do can be hacked.
Can the Hacker see my app's Swift Code, do they only see the list of variables
A sophisticated hacker can see the executable binary but not the Swift source code.
values stored in NSUserDefaults?
It is trivial to see the contents of NSUserDefaults. See iExplorer and other similar apps.
Could I create my own "encryption" in my code
Sure, but should you?
"Schneier's Law": "Anyone, from the most clueless amateur to the best cryptographer, can create an algorithm that he himself can't break."
Is this safe?
No it is not safe. If you want use encryption you need a standard encryption algorithm such as AES but it is not that easy to create a secure scheme. You can use a wrapper library such as RNCryptor. But this creates a new problem: where to safely save the encryption key, see next point.
I don't want to have to learn KeychainsWrappers if my manual solution is safe.
Only if you want to securely wan to to save keys and small amounts of data. Security is hard.
You need to evaluate the level of security you need, this included the level of attacker and the value of the data. Attackers run from curious students to nation states. Data values run from Tic-Tac-Toe high scores to nuclear arms details. You need to determine these first.
NSUserDefaults is just a plist stored in the device filesystem. Its only 'security' is that people have to go into the device filesystem to get to it, which isn't particularly difficult.
According to the apple docs about in app purchases:
After making the product available, your app needs to make a persistent record of the purchase.
source
You can read more in the section about persisting your purchases for more information, but ignore the parts where it says you can use user defaults to do so.
Also I can't ever recommend rolling your own secure storage system if you don't know what you're doing.
The above is assuming you are talking about in app purchases. If you are talking about stuff local to the user, does it really matter if they hack your app? Say you have a system where you have to beat the previous level to unlock the next level. Who really cares if someone edits their defaults to unlock the next level. Its not something they had to pay for so it doesn't affect your revenue stream. In fact, I would argue it's better to allow people who really want to cheat to do so as long as it doesn't affect your revenue or other players.

SQLite Security in iOS

I am developing app, which uses sqllite db. I want to provide security to DB. Is there any ways to provide security to SQLite DB so that no one can read it by hacking device or something else.
Should we provide any encrytion or apple provides their own security? Which are ways to provide app DB security?
Thanks
#Quentin's comment is right - as long as someone has physical acces to your device, it's only a matter of time until it's cracked. However, you can make that amount of time take so long that it's not worth it.
If you were to encrypt your database, the decryption key would also have to be stored on the device (assuming you want it to work offline). You could use the keychain to store this key - then they have to crack the iPhone's keychain before they can get access to your data.
The other alternative is to only let your app work while online - store the key on your server and have the user login and authenticate before you pass the key back to the app. This s a bit more work from you but will ensure that the key and the data are stored in different locations.
Finally (and most securely), you could store everything on your server - that way you control the data nd the key yourself and deice theft won't make the slightest bit of difference. however, if your data set is big this might make the ui of your app more complicated. And it won't work offline, obviously :)

Protect an sqlite file on IOS

I have some data I’ve spent months collecting, cleaning and structuring. The app I'm building will be able to search the data. So far I'm storing the sqlite file in the users filesystem and not on a remote server because I want the search result to be instant to give users the best experience possible, independently of their connection speed.
But I've just discovered anybody with a jailbroken phone can just "steal" the information store in my sqlite file.
The last thing I want is for someone to get the result of my hard work and publish it on a website which could potentially makes the app useless.
Is there any way to stop this from happening?
Thanks for your help!
What you want is a form of DRM. Ultimately, DRM cannot prevent a dedicated attacker from getting at the underlying data. Anything the user can access can, in theory, be accessed by a malicious application.
You can encrypt the rows of the database and hide the key somewhere in the app, but an intrepid hacker will find it. You can download the whole file on first run and encrypt it with a key unique to that device, but then you have to store the key somewhere or have an algorithm for regenerating it--and a hacker can get at either (even if it's in the keychain.) If you require a network connection and use a key generated from something server-side and client-side... well, an attacker can just spoof the request and get that server-side component anyway.
So it really depends how secure you want to be. If you just want to keep honest people honest, simple encryption is often good enough. If you want to make a bulletproof DRM system... you'd be the first to accomplish it.
You can use Encrypted Core Data to secure your data.
This library actually decrypts your database at runtime. You can leave your PASSCODE in your .m file. (My assumption is that it is difficult to get the hardcoded PASSCODE from the object file)
And as #jonathan put it, if some person is desperate to get your data, they will.
EDIT:
As Zaph mentioned in the comments section, do not try to put password in your code either directly, or by obfuscating them in your code by some logic, as any one who is desperate to get your key could reverse engineer your binary and get it.
Is it possible to reverse-engineer my iPhone application?

Data protection on mobile devices

I'm storing some healthcare data on a mobile phone and I'd like to know what the best system of encryption is, to keep the data secure. It's basically a bunch of model objects, that I'm serializing and storing using NSKeyedArchiver / the equivalent on Blackberry (the name eludes me for now)
Any tips? I don't want to make up security protocols as I go along, but one of the other threads suggested the following approach.
Generate a public / private key pair
Store the public key
Encrypt the private key with a hash of the user's password.
Use the public key to encrypt the byte stream.
Decrypt the pvt key, keep it in memory, whenever the user logs in, and decrypt the stored data as needed.
Is there a more standard way of doing this?
Thanks,
Teja.
Edit: I appreciate it that you're trying to help me, but the things currently being discussed are business level discussions, on which I have no control of. So rephrasing my question, if you ignore that it's healthcare data, but some confidential data, say a password, how would you go about doing it?
There might be an easier way for secure data storage. With iOS 4.0 apple introduced system provided encryption of application documents. This means that the OS is responsible for doing all the encryption and decyryption in a fairly transparent way.
Applications that work with sensitive user data can now take advantage of the built-in encryption available on some devices to protect that data. When your application designates a particular file as protected, the system stores that file on-disk in an encrypted format. While the device is locked, the contents of the file are inaccessible to both your application and to any potential intruders. However, when the device is unlocked by the user, a decryption key is created to allow your application to access the file.
So only when your app is active, the files can be read back in unencrypted format. But the nice thing is that they are always encrypted on disk. So even if someone jailbreaks the device, or backs it up, the retrieved files are worthless.
This was probably introduced to conform to some specific data security standard that is required. I can't find that anywhere though.
For more info see the iOS 4.0 release notes.
http://en.wikipedia.org/wiki/HIPAA
Make sure you read and understand this!
edit: Sorry, didn't even bother to check to see where the OP is from, but even if they aren't from the USA there are still some good practices to follow in HIPAA.
HIPPA is a business practice and total system level privacy/security regulation. As such, an app can't comply by itself on random hardware for a random user. You need to determine how your app fits into a client health care provider's total regulatory compliance process before you can determine what algorithm might be found to comply with that process.
My best advice would be, don't store sensitive data in the user's mobile phone.
If that is not an option for you, then some kind of public/private key encryption, such as one you described, would be the next best option.

Securing Coredata objects

I am working on an application which has got some sensitive information. I am aware that it would be difficult for a layman to hack into iphone to get the information. If I use SQLite directly I have something called SQLite Cipher to encrypt / encode the database.
Is there anyway where I can have the same way of encrypting the coredata so it makes it hard for hackers to get into the data.
Can someone shed some light on this?
Thanks in Advance
Core data is now encrypted by default (hardware encryption) on iPhone 3GS and later devices, including iPad. This means that data is automatically encrypted with a hardware key. In iOS 4 or later, by following the steps at Nick Harris' more detailed blog entry, a second layer of encryption (called 'data protection') can be enabled which also uses the user's password to encrypt the hardware key.
All of this depends on users setting a secure passcode and enabling data protection in iOS 4. If you're a registered apple developer, you can also watch the WWDC 2010 video on "Securing Application Data" in iTunes at this link and look at the PDF of the slides here after entering your developer id and password, for more detailed information about file encryption.
To enable data protection, in your - (NSPersistentStoreCoordinator *)persistentStoreCoordinator call, just change the file attributes of your .sqlite file using the key and value below. See Nick Harris' blog for more detailed code, including how to check to see if iOS 4 or higher is active.
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"MyAppName.sqlite"];
NSString *storePath = [storeURL path];
NSDictionary *fileAttributes = [NSDictionary dictionaryWithObject:NSFileProtectionComplete forKey:NSFileProtectionKey];
[[NSFileManager defaultManager] setAttributes:fileAttributes ofItemAtPath:storePath error:&error]
The Core Data Programming Guide says explicitly that the SQL store type is a little more secure than XML or binary, but is not inherently secure - it recommends an encrypted disk image. Unfortunately, that's a little hard to manage on the iPhone.
What you might consider, if this is a real concern for you, is to build your own persistent store type - the Guide has a section on creating your own atomic store, and refers you to the Atomic Store Programming Topics document. Build a store that takes some key from a user prompt at startup, then initializes with that key for encryption and decryption purposes. (Note that if you take this route, the NSPersistentStore class reference says that subclassing NSPersistentStore directly is not supported in Core Data - you should subclass NSAtomicStore instead.)
If someone is using a jail broken iphone there is absolutely nothing you can do. The functions you are using for encryption and decryption can be hooked to obtain the key/iv used. You can also do nasty things like do full dumps of the flash, keyboard buffer, and other "debug" info.
To make things more difficult you can limit the amount of time a secret is stored on the device. Store secrets on a remote system and transfer them via ssl, delete them when you don't need it. This protects against someone stealing the iphone, jail breaking it, and then dumping the database. I'm not sure if this is an attack that threatens your specific application.
In terms of a "layman" (people who can't read? :) Then you don't have much to worry about. Apple has protection in place to keep installed apps from reading/writing to each others resources.
You can add a category for an entity, which overrides reading and writing values to the persistent store. You can then hook into CommonCrypto routines for private- and public-key encryption and decryption of those values as they are stored and retrieved by your application.