Apple advise using NSUserDefaults to store all your app preferences. However, it seems that NSUserDefaults is very easily editable. Is there a way to secure this. I'm not looking for a way to make it impossible to edit, just making it harder so that users won't be so tempted to change application internal variables.
7 Answers
If a piece of data is not sensitive (e.g., default font size), store it in NSUserDefaults.
If it needs to be secure from casual snooping (e.g., user's password), store it in the Keychain.
If it needs to be secure from the user (e.g., registration code), you will need to roll your own encryption, then store the data wherever you like.

- 82,288
- 22
- 110
- 138
-
2Keychain will persist values beyond uninstall. Bare that in mind when using it – xximjasonxx May 03 '17 at 14:36
I wrote a simple to use and small category for exactly that purpose. Works on iPhone and Mac OS X, it is free and under MIT license. You can find it at github: SecureUserDefaults

- 109
- 2
You can store really secure data in the iPhone Keychain. The alternatives to that are your own encryption classes (may limit application distribution), or obfuscation through some other encoding like nsdata, base64, etc.

- 21,746
- 10
- 51
- 63
NSUserDefaults should only contain settings that you want your user to be able to change. App internal data should not be in NSUserDefaults. Save your internal data in an NSDictionary and write it to a separate file in your apps documents or tmp folder.
NSDictionary* dict = [NSDictionary dictionaryWithObjects:objs forKeys:keys];
BOOL succeeded = [dict writeToFile:[self dbFullPathName] atomically:YES];

- 75,956
- 16
- 112
- 147
Use a cryptographic algorithm like AES to encrypt the data you store in NSUserDefaults. Keeping the encryption key embedded in your app, either hard-coded or computed using a succession of operations over multiple elements would successfully deter any editing initiative over the values you store. To make things easier, you should write a wrapper method that takes a clear-text key and value, encrypts them, and then stores them in NSUserDefaults for you, and, of course, does the same thing in reverse when reading the values back. Do note, however, that this will be slower than insecure storage, taking into account the time to encrypt/decrypt, so consider applying the technique only to the most sensitive configuration options of your app.
for iPhone? They can't alter these variables, there's no Terminal.app to change this (except jailbroken devices, but this is a problem for Apple, not for you). For desktop apps, you can encode it using NSData, and they will be archived as base 64.

- 1,856
- 11
- 12
-
1
-
1"this is a problem for Apple, not for you" I dont think thats valid. If your app stores something valuable, its only a matter of time before someone makes a worm/virus that targets jailbroken phones and scoops up that data and mails it home. – AlBeebe Sep 05 '11 at 18:50
-
If you need to store anything sensitive, use the Keychain, not NSUserDefaults. – Marcelo Alves Sep 05 '11 at 22:03
-
but there r still things we can do to prevent insanely high scores on the game center leaderboard – OMGPOP Jun 12 '12 at 03:09
-
To be honest, this seems like a nonissue unless you want to store something in NSUserDefaults
that should be kept secret from the user. Users don't really go in to their preferences and edit them directly, unless there's something hidden in there that can't be changed through the UI (like hidden preferences that Apple doesn't give you a UI to change, but that have real, stable, useful effects if changed).

- 7,839
- 6
- 45
- 82