Shall I encrypt data files in an iPhone game? - iphone

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.

Related

(Idle Game) offline increment issue and saving this data in a secure way

I am working on idle game project but the problem is saving offline progression. I also want to be able to keep the same values in the upgrades the way they were when the player exited/offline. I do not want to save using PlayerPrefs as its unsecured and allows people to cheat. Anyways I hope someone can give me some sort of direction here. I am not asking for the answer just a pointing hand to guide the way. I have attempted searching for this but did not find any answer. Thanks in advance.
The Desired security level is more important than the method of implementation.
Think about it, you want to store data locally, you can not guarantee that your data is not going to be hacked, but you can make it harder for the hacker.
PlayerPrefs normally store data in plain text, you can encrypt data and then put the data in it. a huge amount of cheaters cannot read or change it now.
Every encryption algorithm wants a Key to encrypt data. you have to put your encryption key inside your client.
You can put it inside your code and create that code in runtime(some math calculations). you can also put your encryption key inside a Unity Scriptable Object, Unity automatically converts this data when in builds the game.
if you are going to put your encryption key inside your code, then do not forget to obfuscate your code.(an other thing to make hacking harder).
When you done all of this, I THINK THIS WILL BE ENOUGH, but again it depends on your desired security level.

Avoiding data loss: suggested reading

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.

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?

Prevent cheating on savedata in iPhone

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.

Best way to persist an XML file on iPhone?

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