Securing Coredata objects - iphone

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.

Related

Security code for IOS app

Currently we are developing a track and trace app for our company. To make this app more secure we would like to to ask the user at first launch for a security code. This security code will most likely be the customer number.
Ones the user sends a request to the server with his trace and trace code the server will check if the security code and the track and trace code are linked.
My question is what would be the best way to store the security code in the app so that the app can ask for it ones a track and trace gets send to the server. We want the user to enter the security code only at first start.
[[NSUserDefaults standardUserDefaults] boolForKey:#"security code"];
would this be an option?
For any secure data you wish to store on the device, I strongly advise you use the Keychain. You can then check for the code's existence within the keychain, and use that if it's available.
See the following documentation below to get you on your feet with the Keychain!
Keychain Concepts https://developer.apple.com/library/ios/#documentation/security/Conceptual/keychainServConcepts/02concepts/concepts.html#//apple_ref/doc/uid/TP30000897-CH204-TP9
How to implement on iOS https://developer.apple.com/library/ios/#documentation/security/Conceptual/keychainServConcepts/iPhoneTasks/iPhoneTasks.html
Reference https://developer.apple.com/library/ios/#documentation/security/Reference/keychainservices/Reference/reference.html#//apple_ref/doc/uid/TP30000898
Sample Project https://developer.apple.com/library/ios/#samplecode/GenericKeychain/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007797
user1805901> This security code will most likely be the customer number.
How guessable is that? You might want to look into a UUID in case of loss. Provide the mapping from UUID to customer number at the server.
WDUK> For any secure data you wish to store on the device, I strongly advise you use the Keychain.
In addition to Keychain, you also have to look at kSecAttrAccessibleWhenUnlocked, kSecAttrAccessibleAfterFirstUnlock, kSecAttrAccessibleAlways, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, and kSecAttrAccessibleAlwaysThisDeviceOnly.
kSecAttrAccessibleAlways and kSecAttrAccessibleAlwaysThisDeviceOnly are poison, and should not be used since the Keychain can leak the data. See iOS Keychain Weaknesses for details (its gotten better, but its can still be a problem).
*ThisDeviceOnly means the secret is not included on a restore to a different device. Its helpful for some Copy/Paste attacks.
And if you don't want the secret on the cloud, I believe the Keychain attributes need to include com.apple.MobileBackup. See Technical Q&A QA1719 for details.
Jeff

How to turn off automatic encryption for core data in iOS 5

I have a large core data store that I dont care about encryption. I am worried about the overhead of the automatic encryption so I am trying to disable it.
The quote from the docs is:
For applications built for iOS 5.0 or later, persistent stores now store data by default in an encrypted format on disk.
This is the code I am using, its not crashing, but im not 100% sure is doing anything. (I got the constant names from here).
NSDictionary* optionsDictionary = [NSDictionary
dictionaryWithObject:NSFileProtectionNone
forKey:NSFileProtectionKey];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:optionsDictionary
error:&error]) {
Is this the right code?
How can I tell if has stopped encryption?
Robert,
All encryption on iOS is performed in hardware. I, and the Apple engineers I've spoken with, would be really surprised if you saw any performance difference with an encrypted filesystem. (Flash on iOS devices is so slow that you will not see the encryption delays.)
As your above commenters suggest, use the simulator and the runtime system that shows you the SQL that is actually issued for your fetches to see what the performance differences between you two fetches actually are.
Andrew
According to the docs, that code should turn off all the file protection even on iOS5. You can't easily test it, however.

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.

How to protect sqlite db in your core-data iPhone app?

I have a Core Data-based iPhone app with a pre-populated read-only database. What protection (if any) can I apply to my database to reduce the likelihood of piracy / the database being read off a jail-broken iPhone?
Most code examples for using a pre-populated sqlite database show the database being copied from the app bundle into the app's documents directory on the iPhone and this is completely visible on a jail-broken iPhone. Instead, I thought about using the database directly from the app bundle as follows:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSURL *storeUrl = [NSURL fileURLWithPath:
[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:
#"MyDatabaseName.sqlite"]];
<... followed by standard persistentStoreCoordinator code ...>
When I put a breakpoint on the store url this returns just another file location which I'm guessing is just as visible as the documents directory in a jail-broken iPhone:
<CFURL 0x139610 [0x38388ff4]>{type = 15, string = file://localhost/var/mobile/Applications/6ACD76F0-396D-4DB1-A46B-B2459A084063/MyiPhoneApp.app/MyDatabaseName.sqlite, base = (null)}
Can someone please confirm if above is correct and/or if there are other ways to address this issue (I'm not looking to encrypt or anything like that ... hoping for a quick protect solution) ? Appreciate a determined hacker will get what they want -- I want to at least put up some resistance if I can.
Thanks
First, yes you can store a read-only database inside of your app bundle and access it directly from there.
Second, the only way to protect the data is to keep it encrypted on disk and unencrypted in memory. This cannot easily be done using Core Data in its current form. What you can do is to encrypt certain columns of the database and decrypt them only in memory. This is accomplished by storing the columns as binary data but that also means you cannot do any searches on those columns.
Update
Even trying to avoid Jailbroken phones (which is not a 100% guarantee that the person is a criminal. Keep in mind that developers frequently jailbreak their phones for honest reasons). will not protect your data. The data is sitting inside of a zip file on their desktop computer and is accessible without ever being run or touching a CocoaTouch device.
If the data is that private then you need to put it on a webservice and never store it on the device. Anything on the device (or any device for that matter) is accessible and subject to reverse engineering.
you could try this:
https://github.com/calebmdavenport/encrypted-core-data
It looks early in development but if you have a simple data model you might be able to get it working. uses sqlcipher.
You could also try Encryption Transformer class's. Can break predicates. If you use nspredicates and depending on your security needs, you can choose an encryption algorithm that preserves relative alphabetical order (roll your own if you have to). this will allow you to use predicates. the bottom of this page explains with code samples how to do it (though you'll need to find a suitable encryption algorithm as their's breaks predicates): http://blog.artlogic.com/tag/encryption/
Encrypts fields rather than the whole database.
stopping/detecting jail breaking won't stop anything. you can open the apps package file on your mac in finder without doing a jailbreak or anything special. syncing to itunes pulls your apps .ipa file down so all you need to do is go to the file and open it to get to the app's package data.

How can I encrypt CoreData contents on an 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.