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.
Related
I am about to work on an app which handles extremely valuable data. Any loss of this data for the user would be very costly, so I'm interested in finding out more about the best architecture design for our needs.
The user will be inputting this data in their iPhone each day. The alternative to using this app is carrying around a piece of paper with this sensitive information on it. So while I know we can be more secure than a piece of paper, I want to make sure we also cover the user stories like "I flushed my phone down the toilet" or "my son deleted the app, where's my data?"
A service like Dropbox comes to mind, but I wouldn't want to require our users to have a Dropbox account; the syncing architecture must be transparent to the user. iCloud is out because web and Android versions may follow.
Can anyone suggest either some good reading on this subject, or some good frameworks to look at? I expect to use a node.js backend, and while we are targeting iPhone first, Android will follow.
The data itself consists of 2 tables, each with a small number of fields, with a many to many relationship. A few new rows will be created by the user each day, but the data will be small and highly compressible.
Turns out this is an extremely difficult issue. In data assurance (this isnt yet a security type situation although could become one because of the assurance aspect) there is ALWAYS a time element. As a simple example what happens if your use has locally updated some piece of data. Just before you have the ability to fully push the data to some cloud service, etc... he / she dumps it in the toilet. Even if good signal was there for transmitting the data there is time in transferring and time necessary for the cloud server to respond saying the data got there properly.
Generally in data assurance, you really have to work to the best you can. You will NEVER be able to solve all issues as there is no data center, nor link to a data center, etc... that is perfect. There is always a chance of data loss. Truly the best you can do, is SYNC as fast as data changes, and if there is loss of connection, as soon as the connection becomes alive again.
Now, for security. Security by itself does not create assurance. If the data itself is something that the customer does not want to lose, and that is his only requirement, then security is un-necessary. If he / she is also worried about other getting their hands on his data, then you have to be worried about data-in-transit (both up and down during syncing), and on the device itself. For the best potential security, encrypt the data locally on the device prior to pushing over the cloud. There are many known attacks that even if using SSL or other services, can get at the data. If you wish, locally encrypt a file, then you could for SOME added security still use SSL (at this point you will have doubly encrypted the data). You also want to sign the data so that there is little chance of it being manipulated in transit, or by the cloud server itself (if a hacker hacked the cloud server). Generally the way to protect the data while on device, you may choose to have the user input a password, and put some fairly strict rules around how passwords are formed, and how many tries you allow before you disallow attempts for 30 minutes or so.
You may also wish to store the data locally in an encrypted form. This way if someone gets the device, they still will need to have the password before they can get the data (unless of course they can crack the algorithm you use to generate the symetric key from the password).
In terms of online data service, you could use iCloud, etc... I am actually NOT a fan of anything cloud. I think it is SO counter enterprise / proprietary data, it isnt even funny. I think it actually almost laughable that so many of these phone / device manufacturers are going SOOOOO cloud based. I think they are abandoning the big companies, as NO big company I know of wants to place their proprietary data on a cloud server that THEY DONT CONTROL. In any case, I would argue that so long as you have a good local encryption scheme prior to sending out the data, then you should be OK. I would from an assurance perspective however look at where the servers are in locale. the reason being that if assurance of data is of prime concern, most larger IT setups like to have replicated data centers on opposing sides of the country / world etc... The reason for this is if an earthquake takes down the data center on one side of the country, it most likely will NOT take down the one on the other side of the country simultaneously. If the data centers for iCloud or whatever you can find are essentially in one locale, then you may consider syncing with one data center on the west coast, and choose a completely differing data center (in this case company) to sync with that is centered on the east coast.
This is all very high level, how you would implement this on an iPhone specifically we could also talk about, byt I hope this at least begins to help pave a path.
I'm making a turned based game for iPhone. I've got a couple of questions.
1.
Shall I bother with encrypting the data that is sent between the players?
2.
I'm also storing data files that contain help data. As an example, one such file demonstrates the game controls. Given the data in that file, it might be possible to make an understanding of the data in the turn data, but I would say that it's quite complicated. Shall I bother with this kind of security issues? I guess the information can be used to be number one on the ranking :). I guess these files are viewable on a jail broken device?
3.
If I encrypt the files, will cheating be eliminated then?
1 / 2: I don't think you should bother with encrypting the files. While it stops them being tampered with, if you're just sending turns back and forth there isn't any real point. Sure, they could be intercepted and changed, but unless this is some AAA game where changing this info would affect a lot of players, I really don't see the point.
3: No, cheating won't be eliminated. Even if you encrypt something, someone will always be able to find a way around your encryption. Sure, there might not be a method now, but there will be some day.
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?
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.
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.