Protect iOS Database information - ios

I am busy writing a commercial electronic words-dictionary type of app for iPhone and iPad iOS7. The value of the app is really in the database that I worked many years on, and not so much the app itself. The database is very large (195mb on a windows computer before converted to something like SQLLite) and I and would like to know what is the best way to protect the data in it so the app can read it but other people cannot read/get to it. It seems most mobile developers use SQLLite, but the data can easily be read with a normal hex editor on it.
From this forum and others I gathered that SQLCipher is a good tool. My problem is that it SEEMS that SQLCipher encrypts the database, and then decrypts it when it needs to be read in a temporary file and then encrypt it again afterwards. If this is the case, I have two problems.
The database is very large and to decrypt it every time and encrypt again is going to make the app very slow.
What stops a hacker from reading/copy the decrypted (temp) file when it's available even for a short time?
Do I understand SQLCipher's working correctly, if so, is there any other tools/methods to encrypt/protect a database so that the program can still read it with SQL Queries without making the data so easily available in any way, or any other suggestions you might have?
Thank you

According to this page: http://sqlcipher.net/design they don't decrypt your database as a whole, so the answer to your question #1 is no. They claim about 5-15% overhead to the standard SQLite performance.
As for #2 - SQLCipher will decrypt database in pages, so theoretically - somebody can get access to that page in memory in decrypted way. However this would be true for any encryption method you use. Just think about it - even if you decrypt full database, your application would need to display/access some data from it, somehow at some point. And at this point data must be decrypted. The only question here - how much of the data will be decrypted at given moment.
The other alternative you have is to try to implement ecnryption/decryption yourself using standard SQLite and standard ecnryption library. You can for example encrypt each row (or even fields with sensitive data) individually and decrypt them when needed - but then again, at certain moment this particular row will be in the memory decrypted and visible to hacker.

Related

Where does HealthKit stores its data?

Health related data for a user is a privacy thing and its need to be very secure i.e. it needs to be stored in secure place. For example, while I was watching Apple's official video on Finger print unlock, they told that finger print data is stored at place where it is impossible to hack. So, for a curiosity, I have a question in mind that where these data are securely stored?
I have had a look at this link from Apple Documentation but could not found the information on it. One thing I have figured out is that data are encrypted and stored but where?
Does anyone has idea on the same?
Apple describes the security attributes of various iOS features in this document. To quote:
This data is stored in Data Protection class Protected Unless Open.
Access to the data is relinquished 10 minutes after device locks, and
data becomes accessible the next time user enters their passcode or
uses Touch ID or Face ID to unlock the device.
Read the "Encryption and Data Protection" section of the document to learn more about Data Protection. Any app can use the "Protected Unless Open" data protection class for its persistent data.
As you already know, NSUserDefaults is simple and effective for saving small, simple bits of data, like NSNumbers or NSStrings, to your device’s file system. But this data is in no way stored securely as hackers can access it pretty easily from the device.
You have figured out that sensitive data are encrypted. But you need to find the answer where it need to be stored. The Answer is:
Keychain Services:Apple has provided the Keychain Services API to deal with this problem and help developers build apps that safely handle passwords and other sensitive information.
Now the question might rase why?? and the answer is:
Keychain is great because data encryption automatically is taken care of before it is stored in the file system so there is no need to waste time building encryption algorithms.
You can go through this link for better explanation.
https://developer.apple.com/documentation/security/keychain_services

iOS: Safe way to store data which gets deleted along with app

We need to store various data (accesstokens, receipts). In bytes this is relatively small (20000 symbols or so).
We don't want the user to be able to read and tamper this data because we to some extent don't want any smart users to bypass our systems in some way.
We don't want this data to be stored after app is deleted. Therefore keychain seems inappropriate. This is wanted because it seems sensible that the user should get a clean install every time they install the app.
If you want to have the data secure you should use Core Data with apples Data Protection on the DB file.
In addition to that you should encrypt the data itself too.
UPDATE:
You may want to give this a look for encrypting the data: RNCryptor
And this for Data Protection: Data Protection

How much access will my users have to a SQLite Database I ship with my app?

I'm developing an iPad app that will rely on a very large database of valuable information. I'm not too familiar with the device myself (I don't have a personal iPad, nor have I ever used one outside of developing this app). Users cannot directly see the data in the database through my app anywhere.
Would there be any other way users could get access to the data in my database (perhaps by plugging the device into the computer and going through Xcode or iTunes)? If not, I've been reading up on jailbreaking a little, and I've seen that doing so can allow a user access to the device's filesystem, so would that allow them to see the contents of my database? Or would it be possible by jailbreaking and installing an app to view database files on jailbroken devices (in fact this question would suggest that it could be quite easy to develop a "database reader" app for jailbroken devices)?
If the database is there, then people can touch it. It's just a matter of being a little more than a power user. They might not be able to read the data from the database if they don't have the credentials to authenticate into it, but then again once you have a database in your hard disk, it's just a matter of patience and knowledge to break into it.
This is a principle that applies to any device and operating system, not just iPad and iOS. If you don't want your users messing up with some file your app uses, you may encrypt it with an obscenely long encryption key. Someone may eventually crack that info... All you can do is ensure that they won't be able to do so before your app is obsolete anyway.
Otherwise, keep your data in a server, where people can't touch it.
I am a Developer (not a hacker) no matter how hard I try to defend my apps, as soon as the code or database is on the device (encrypted or not) I treat the data as public. if the decryption key is passed to the phone and decrypted on the phone, then consider that data public too. basically you are screwed. Give up defending your apps. and just start building cooler stuff, and use HTTPS when sending data over the internet, thats all I can ask for. Defending your keys, api tokens, high scores, coins, etc.. is quite literally impossible. yes do a little to try, but your efforts are fruitless. Every day the public hacker tools to see inside locally encrypted databases, locally encrypted apps, see inside obfuscated apps, is getting better and better every day. you can't beat it. developers are not smarter than hackers, period. Giving the end user a false sense of security. its like locking your house, or locking your car, can you stop someone breaking in? nope. the only way to solve it is to build a big ass bank (aka server), put some tellers at the front desk (aka cloud API), and be done with it.
I'm not an IOS developer, but I do know SQLite. You can encrypt databases in SQLite - look for sqlite3_key_v2() documentation. Your application will need to have the password internally, but you can make it difficult for a hacker to get at that. Don't use a static string as your password - instead take some string and then manipulate it programmatically. This will make it more difficult, though not impossible for an attacker to recover the key. But it will add an order of magnitude more complexity to get at. The attacker will have to get access to the database file itself, and then will have to reverse engineer your app in order to recover the database password.

iOS Data Storage Guidelines catch 22

I've browsed through about 2 dozen articles here and elsewhere looking for an answer. No one seems to have addressed this problem --
We have an application that has fairly large database (on the order of 5MB). The application needs the DB when working offline. The DB can be recreated by downloading from our server when online.
We can't use Core Data instead of our own DB because the data must be encrypted to meet government privacy standards.
The app cannot function offline without this database, so it can't go into Library/Caches.
We can place the data in Documents and mark it "do not backup" for iOS 5, but this doesn't work for iOS 4 since that attribute is not recognized.
So what can we do with the database in iOS 4?
Just off the top of my head.
I guess you could subclass NSManagedObject so that it encrypts any data that gets saved to Core Data and decrypts it when you read it. There will be a lot of overhead on the CPU though. There might be someway to optimize it.
Check this out: AES Encryption for an NSString on the iPhone
Put it in (sandbox)/Library/Application Support. Here is how Apple describes the Application Support folder:
Resource and data files that your app creates and manages for the user. You might use this directory to store app state information, computed or downloaded data, or even user created data that you manage on behalf of the user.
Quoted from Apple's File System Programming Guide for iOS.

Syncing a local sqlite file to iCloud

I store some data in my iOS app directly in a local .sqlite file.  I chose to do this instead of CoreData because the data will need to be compatible with non-Apple platforms.
Now, I'm trying to come up with the best way to sync this file over iCloud.  I know you can't sync it directly, for many reasons.  I know CoreData is able to sync its DBs, but even ignoring that using CD would essentially lock this file into Apple platforms (I think? I've only looked into CD a bit), I need the iCloud syncing of this file to work across ALL of iCloud's supported platforms - which is supposed to include Windows.  I have to assume that there won't be any compatibility for the CoreData files in the Windows API.  Planning out the best way to accomplish this would be a lot easier if Apple would tell us any more than "There will be a Windows API [eventually?]"
In addition, I'll eventually need to implement at least one more sync service to support platforms that iCloud does not.  It would be helpful, though not required, if the method I use for iCloud can be mostly reused for future services.
For these reasons, I don't think CoreData can help me with this.  Am I correct in thinking this?
Moving on from there, I need to devise an algorithm for this, or find an existing one or an existing 3rd party solution.  I haven't stumbled across anything yet. However, I have been mulling over a couple possible methods I could implement:
Method 1:
Do something similar to how CoreData syncs sqlite DBs: send "transaction logs" to iCloud instead and build each local sqlite file off of those.
I'm thinking each device would send a (uniquely named) text file listing all the sql commands that that device executed, with timestamps.  The device would store how far along in each list of commands it has executed, and continue from that point each time the file is updated. If it received updates to multiple log files at once, it would execute each command in timestamp order.
Things could get 'interesting' efficiency-wise once these files get large, but it seems like a solvable problem.  
Method 2:
Periodically sync a copy of the working database to iCloud.  Have a modification timestamp field in every record.  When an updated copy of the DB comes through, query all the records with newer timestamps than some reference time and update the record in the local DB from the new data.
I see many potential problems with this method:
-Have to implement something further to recognize record deletion.
-The DB file could get conflicts. It might be possible to deal with them by handling each conflict version in timestamp order.
-Determining the date to check each update from could be tricky, as it depends on which device the update is coming from.
There are a lot of potential problems with method 2, but method 1 seems doable to me...
Does anyone have any suggestions as to what might be the best course of action? Any better ideas than my "Method 1" (or reasons why it wouldn't work)?
Try those two solutions from Ray Wenderlich:
Exporting/Importing data through mail:
http://www.raywenderlich.com/1980/how-to-import-and-export-app-data-via-email-in-your-ios-app
File Sharing with iTunes:
http://www.raywenderlich.com/1948/how-integrate-itunes-file-sharing-with-your-ios-app
I found it quite complex but helped me a lot.
Both method 1 and method 2 seem doable. Perhaps a combination of the two in fact - use iCloud to send a separate database file that is a subset of data - i.e. just changed items. Or maybe another file format instead of sqlite db - XML/JSON/CSV etc.
Another alternative is to do it outside of iCloud - i.e. a simple custom web service for syncing. So each change gets submitted to a central server via JSON/XML over HTTP, and then other devices pull updates from that.
Obviously it depends how much data and how many devices you want to sync across, and whether you have access to an appropriate server and/or budget to cover running such a server. iCloud will do that for "free" but all it really does is transfer files. A custom solution allows you to define your syncing model as you wish, but you have to develop and manage it and pay for it.
I've considered the possibility of transferring a database file through iCloud but I think that I would run into classic problems of timing - slow start for the user - and corrupted databases if the app is run on multiple devices simultaneously. (iPad/iPhone for example).
Sooo. I've had to use the transaction logs method. It really is difficult to implement, but once in place, seems ok.
I am using Apple's SharedCoreData sample as the base for this work. This link requires an Apple Developer Account.
I did find a much much better solution from Tim Roadley however this only works for IOS and I needed both IOS and MacOS.
rant> iCloud development really has to get easier and more stable! /rant

Resources