0

I have been reading many different posts, threads, etc. regarding the best practices to store level data to be used throughout a game application (level boundary data, images, characters, time, etc.).

  • Many have suggested that using a Property List (.plist) is appropriate, as it is quite simple to store the game info then read it when needed. While this is easy to create and refer to, plist files are not exactly secure in any way, aside from simple AES encrypting the string contents.
  • Another method would be perhaps to hard code this data into a separate class file, titled LevelData.m and refer directly to the class to read the level data, as storing it this way should be "safer", as (from what I am aware of) users do not have direct or any access at all to these class files once an application has been packaged and distributed through, say the iOS App Store.
  • I have also read to use SpriteKit's built in NSCoding, where the data can be archived into a file (or NSData object) and later unarchived from that archive.

My question, can anyone suggest the best approach, or perhaps one that I haven't mentioned? YES, I understand they are all perfectly valid methods to saving big data, particularly non-trivial, and somewhat repetitive data that just needs to be read, and all have their pros and cons in terms of security measures. I am merely just trying to find the safest way to store this data without the user being able to tamper it in any way from other people who may have encountered a similar issue and have found the ideal solution.

NOTE: I'm sure that hosting this data server side and retrieving the data upon application launch would be the ideal secure approach. However, I am just looking to see which method should be the best practice in terms of security strictly through storing data on the device. Thanks!

Will Von Ullrich
  • 2,129
  • 2
  • 15
  • 42

2 Answers2

1

If you are distrusting the users, how about signing the data which's integrity you distrust and validate the signature using public key encryption (with a pinned certificate in the binary)?

Thus, only data with a valid signature from you can be used.

Yet, after all, if a user dissembles your binary and modifies the public key, that doesn't work either.

As always with those problems, the question is: how hard are you making it for an adversary to break your security meassures - and what hardness is useful?

Tobi Nary
  • 4,566
  • 4
  • 30
  • 50
  • Exactly - I get that there are always people who are willing to work past any and all means of protection. I'm just looking to be able to store my data as easy as possible with AES level encryption. I'm not quite sure what you mean by using a signature validation. Is that any different from just encrypting the data? – Will Von Ullrich Jan 26 '16 at 17:11
  • 1
    Yes, it is. Yet, to explain that, security.SE might be the right place, since **crypto is hard** and an explanation of (a)symmetric encryption and differences does exceed the limits of SO. – Tobi Nary Jan 26 '16 at 17:17
  • Im not quite sure what security.SE is - is that just enhanced security? – Will Von Ullrich Jan 26 '16 at 17:31
1

I know you got an answer already but I personally use a GameData Singleton class with NSCoding. I than save the encoded/archived data into iOSs Keychain (instead of NSUserDefaults, NSBundlePath etc).

To save into keychain you can use this helper

https://github.com/jrendel/SwiftKeychainWrapper

which is the one I use for my apps. Its works very similar to NSUserDefaults and is therefore very easy to use.

You can also get a more complex and feature rich one here.

https://github.com/matthewpalmer/Locksmith

crashoverride777
  • 10,581
  • 2
  • 32
  • 56
  • Would it be ill-advised to create a Class that contains the level data and pull it from there? – Will Von Ullrich Jan 27 '16 at 16:47
  • I don't think so. I believe all that matters is how the game data is stored on your device. If you use NSUserdefaults or Plist than I think people can change saved data because it's in plain text and not encrypted. I don't have games yet with level data but it should be the same idea as far as I understand. – crashoverride777 Jan 27 '16 at 16:50
  • I see - what i mean is that I would be storing Level Specific Data (enemy count, objects, bla bla), where as the actual User Data that gets created by the user playing each level is getting encrypted and saved through Common Crypto. I feel like hard coding Level Data into a class should be safe enough no? (preventing anyone from changing what each level should contain) – Will Von Ullrich Jan 27 '16 at 16:53
  • I think so yeah, I am quite a novice at this as well. I don't think you need to safely store enemy counts etc this way, there is probably no need for it. However you want to safely store things such as highscores or in app purchases. Say you have an allLevelsUnlocked bool and save it in plain text (user defaults, Plist), a person could than change this bool and use that feature without paying for it. I think however that it is overkill if you try to encrypt things such as enemy count as well. – crashoverride777 Jan 27 '16 at 17:00
  • A good read is this http://stackoverflow.com/questions/27566483/storing-game-preferences-and-saved-games-in-a-secure-format – crashoverride777 Jan 27 '16 at 17:05