I am making an iPhone application, in that my all the content is stored in the sqlite database.
Now there is always threat of Jailbreaking and other Spam activity. So Came to know that Mac/windows can access the application directory directly using some softwares.
So I want to keep my database secure as well as If any one shall modify / replace the database then when I start my application I should be get notified using codes that Some changes are made with the database.
With iPhone how this things will be performed can any one suggest ? any tutorial or code ?
I am going to store data in encrypted formate with some Encryption algorithm but how to protect SQLITE database from modification that I want to know.
thanks in advance.
You really can't know.
If you want to make a best-effort, you could do something like compute an sha512 or sha256 checksum of the database, and store that in another file, but it'd require reading the entire database at every application startup and shutdown, which would probably not please the user. That takes time, more time than just letting SQLite3 do its magic on reads and writes.
And someone malicious could modify the stored checksum, too. (It'd be easy enough to figure out how you're doing it, if they have access to your program's object code, so there's no real point in trying to obfuscate a hypothetical hash checking routine.)
Anyway, it's their data, right? :) so if they want to fiddle around behind the scenes, let them have at it. You need to make sure that any inputs you accept on your servers are treated with the same distrust you would use when accepting input from a web browser.
Related
I'm developing an app that's pretty simple, and the important part of it is the content, which consists of lots of info that has been gathered over many years. I want to format it in a nice way to show to the user.
When the user downloads the app and first loads it, it goes to the server to get the whole database into the phone. Then, he can see the important items, and sort/filter through them. To avoid somebody taking my database, I'll use a SSL connection. I know if they want they could use the app to see every piece of content one by one, but there's nothing to do about that.
The thing is: I have the data in the cloud (mine). I can securely download it using an SSL connection (any other ideas to secure the transfer?). When I get it here, I'll save it in a db (Core Data is the obvious choice).
How can I secure the data in the internal database, so if the app is hacked, someone cannot access the db? I would put it in the keychain but it's a rather large db for that and it's not that important. (It's not sensible info, just info I don't want anybody to get massively.)
The other thing I could do is to never store anything in the device and have the user always making calls to the cloud, but I think this would be too time consuming. And just give him the option to save their favorite picks to the device. But that's too time consuming and there is the sync issue.
This is a reference I looked up about a similar issue, without the part I'm asking answered:
How to encrypt iPhone upload and download of info?
Basically, the only choice is to use SqlCipher. Of course, you have to port it to iPhone yourself (unless someone else has posted a port since last I looked). But it's not an insurmountable task.
Of course, even with SqlCipher you have the challenge of storing the key somehow. There's no really secure way to do this -- you have to use some form of "security by obscurity".
Why not just have some private key info stored in the code, and then when you want to download the database just have it query the server with the key? That way you wan't need to worry about SSL or encryption in the downloading part. In regards to storing it I agree with Hot Licks, SqlCipher appears to be the best and only option. However watch out for encryption, as you will have to declare it to apple and get all kinds of export permits (http://stackoverflow.com/questions/2135081/does-my-application-contain-encryption).
Hope this helps,
Jonathan
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?
We can use sqlite, nsuserdefaults or ordinary file system for saving gamedata on iPhone. These data are usually stored in the Documents directory, but files under the Documents directory can be easily modified without JailBreak. (Actually some cheated scores were posted to the server before)
There are some ideas I considered to prevent cheating by modifying save data.
Encrypt file
Simply encrypt data file and decrypt it on reading. It seems secure but the performance will be sacrified if the game need to update gamedata frequently.
SQLite encryption
There are some encrypt extension libraries for sqlite. The problems are the cost and the licenses.
Verifier / Checksum
Store the checksum of saved data and detect cheat by using it. It might cause FALSE POSITIVE result if the saving checksum failed by some reason.
Keychain
Store data into keychain. But we can't use sqlite. And is it okay to store large data in keychain?
Each idea has a flaw. Can you give me any ideas?
One flaw in the design seems to be that you are trusting the local data. Instead I'd recommend that you treat the local data as unsafe user data. That way, a user can manipulate it all they want, but you'll never send it to your server to be published.
When a user completes a game, have the game send the score to the server right away. If you like, your server can send back a signed copy (hashed) that you can save wherever you want in whatever format you want. In your game, you could add a little "verified score" badge next to the scores that took place while they were online. If the verified score is manipulated, then the hash won't work, and (locally anyway) they'll loose their score.
If your user is offline, then their score cannot be verified. You can still save it locally with all the signed scores, but don't have to worry about syncing up bad data at all. Simply never send data to your server that was read from the local filesystem.
From a user experience perspective this may not be ideal, but you can frame it by telling your users "If you are connected to the internet when you get a high score, your score will be verified and published in the global top list" or something to that effect. I'm sure you can figure out a way to handle it.
There are some very light, if darn near unbreakable, ciphers for encoding if you want to go that route. I've used in the past a variation of the substitution cipher where I XORed the values with random numbers. These can be darn near unbreakable (esp. if you change it up each time - nothing more frustrating to a hacker than to get differing results each time :)
The smaller the data, the easier it is to back-hack. Nothing is more frustrating than sniffing a network and finding that 10 digits are encoded in a 4096 digit block of random numbers.
Depending on the size of your data, you could encode different parts with different ciphers - it would be lightweight to encode/decode but a pain to hack.
You can save the data in a sub-folder of NSLibraryDirectory instead of NSDocumentsDirectory. Users cannot see or edit the NSLibraryDirectory through iTunes.
I'm using MonoTouch and also System.Data to create a DataSet (just xml to those not familiar) for simple data binding. Data on my app is minimal so no need to go all out with SQLLite. The dataset use makes it easy to pass via web services for cloud sync.
I serialize the DataSet to the personal folder on save and of course read this file when the app starts up to load up the user's data. I've had issues where this file is becoming corrupt and I'm not sure why. I assume file I/O may be slow on these devices and that could be the cause, I'm not sure, but it is happening.
I'm also concerned that maybe iTunes is passing this file back and forth between the PC/MAC when the user syncs their devices with iTunes, which may be the cause of the corruption?
I want to prevent this device file from syncing with iTunes and also reliably persist it. I'm using the NSFile.Save option to save it to the device. I'm thinking since it's a text file maybe I could more safely store it in the standard user settings area instead? This would prevent it from being synced by itunes, I presume?
What is the most reliable and safe way to handle this file i/o for the xml dataset storage?
Thank you.
You're using MonoTouch. Isn't it simply a matter of calling DataSet.WriteXml() with a FileStream object ready to write to a document in your Documents folder?
That Documents folder is backed up to iTunes. It's not synced, but it helps if your user is restoring their phone (because they bricked it, lost it, whatever). It doesn't explain why it's corrupt.
The only thing that I can think of why it's corrupt is because it took too long for your app to write it. There's a limited time from the point where the user exits the app until it's closed down, to prevent apps from keeping the system hostage and deteriorate user experience.
If writing the whole dataset takes too long, you want to think about minimizing that. Perhaps you can just store the data, and not the schema. Or you can devise a way to store only the deltas on exit and reconcile when the user has loaded your app again.
You can also prevent complete loss of data by writing to a second file, and when that operation completes delete the old file and rename. That way, the next time you start up if the write operation didn't complete, the old file would still be there and the user would have only lost their more recent changes.
In any case, if your data gets too big for a simple write operation to complete, you should look at different options such as sqlite.
Your best bet is probably to just save the XML as text. It's as simple as File.WriteAllText(...) - there's no reason to go to NSFile for this. That's part of the advantage of MonoTouch :)
Regarding syncing, here's the rule:
If you keep the file in the user's documents folder (Environment.SpecialFolder.MyDocuments and Environment.SpecialFolder.Personal BOTH point to the user's doc folder), then it's going to get backed up whenever the user syncs with iTunes.
There's nothing wrong with this. It persists the data between sessions and makes it recoverable if something goes wrong with the user's phone and they need to restore from a backup. Since your question is about persisting an XML file on the phone, this is what you want.
As for the iTunes question, there's no problem with speed and syncing because your app isn't going to be running while the phone is syncing. The file will either have been saved or it won't. Any corruption that takes place is happening while your app is running.
Reasons for files getting corrupted can include:
Not saving before the user quits. You get a chance to do this.
Not gracefully handling an incoming phone call. The system warns you about this as well.
iTunes definitely isn't corrupting your file. If that were the case, iOS apps would all be broken. It could be happening on your dev machine for whatever reason, but I've never seen this happen elsewhere, and I've done quite a bit of iOS development.
If you'd like a tutorial on reading and writing files, I posted an answer in another question.
It's lengthy, but the point was to answer as many questions as I could so nobody would be left hanging or confused.
A nice thing about iOS devices is that you're back (for most apps) in the one-person-at-a-time world. You're writing apps where you don't have to worry about 5,000 people trying to use your web-based app at the same time (that's not always true, but... you get the point). As a result, you can do things that you might normally consider bad for performance, but you're unlikely to see any performance problems (as long as the file you're saving is either small enough to be saved quickly or you're saving in the background on another thread - you never want to block the main (UI) thread with a heavy IO operation).
If you have any more questions, feel free to ask.
I hope this helps :)
Lots of frameworks are read-only, but I've found that GDataXMLNode from http://code.google.com/p/gdata-objectivec-client/ works very well read/write.
Having said that, on the iPhone you'd do yourself a big favour using Core Data with a SQLLite backend. :-) Apple has done all this for you and optimized it more than any of us every will
Cheers
Nik
Consider using SQLite, I'd go for something like
http://www.taimila.com/entify/ (not tried yet)
catnap orm
or Faks sqlite-net on google code (using this in a few apps)
entify - if it does what it says it can do - looks really good.
persisting XML on the iPhone as a means to store and access data is a nause you dont want to get into. I wrote about it here http://iwayneo.blogspot.com/2010/08/festival-star-history-serialization-as.html
I like to use CoreData and their entity model into my projects.
I need to know that how to store sqllite database into Iphone securely.
As everybody knows when the Iphone broken with jailbreak it have file system navigatable, that mean for me, someone or somebody easly open or copy to another envorinment my sqllite db. How do i protect my db for these issues ?
Thank you
Answer in bold.
If they have jailbroken your iphone and have the will to steal data, they will probably have the ability to decrypt anything you put there; this is especially so if the data is of any value. To use encryption in this scenario your application will have to store the password somehow, unless you expect the user to enter this every time using the iphone keyboard -- which is a big no-no from a usability point of view. I suggest you rely on the access baricades and remote-wipe facility provided by apple.
If your a going to rely on apples 4-numeric pin as a password -- i.e., to balance useability.... well that only has 10,000 combinations.... not very secure.
However.... the simplest and the time-tested approach is to use a reversible encryption block-cypher in block-chained mode to encrypt the content of the sensitive columns, and to retrieve the password from the user every time the application is started.
-- edit : further discussion --
If I was expecting contents to be encrypted in a mobile way, I would expect the user of the contents to have a USB stick with the contents on it and a security hardened laptop/netbook with the something like truecrypt running on it.
I was not aware that a phone can be jail broken without the consent of the user ?
On the iPhone 3GS all data stored on the phone is encrypted.
I don't know what you are storing, but leaving the security to Apple may be OK.
Did you read this?
http://images.apple.com/iphone/business/docs/iPhone_Security_Overview.pdf
If you really only have under 10,000 records, and they are smallish - like say a short string or two in size, then you could just use an NSDictionary / NSArray with 10,000 items in memory at a cost of 10k*.256k = 2.5 MB in memory, which is not much. If the queries will be simple, then you don't need sql at all. Just run through all records on each search.
You could store an NSDictionary as an exncrypted file, password protected, with the user entering the password on each launch.
Are you worried about someone who has stolen the phone getting the information? Or the person who owns the phone getting to the files your app contains?
If it's not the user there are safeguards you can take, like the password presentation every time (hint: users will hate it and your app will get all 1-star reviews).
If it's the user you are worried about, you are insane to think you can protect anything the user has on their own device. You can just apply some simple obsfucation and call it good.