Can Keychain be used like a NSUserDefaults
on steroids? I mean, for example, to store NSData
used in a game?
My intent is to store a NSData
element that will be essentially the representation of an array or dictionaries.
So the questions are:
Suppose I create a wrapper using Apple's KeychainItemWrapper
class. Is this kSecValueData
mentioned on the keychain documentation referring to a NSData
object?
If so I can do this, right?
NSData *myData = [NSKeyedArchiver archivedDataWithRootObject:myArrayOfDicts];
KeychainItemWrapper* keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@"myID" accessGroup:nil];
[keychain setObject:myData forKey:kSecValueData];
Second question: if this is the case, is there a limit on the NSData
size that can be stored on keychain item?
I don't think there is any limit and you definitely can store NSData, however performance will not be very good. Quoting Apple's documentation:
The keychain is intended for storing small amounts of sensitive data that are specific to your app. It is not intended as a general-purpose mechanism for encrypting and storing data.
I wouldn't store more than 1KB or so in a keychain entry, and you should also avoid having a lot of keychain entries.
If you need to encrypt a large amount of data, you should generate a random AES-256 key and store the key in keychain, then encrypt your large data using AES. Look up RNCryptor on keychain for a good library to implement this properly and ask any specific encryption questions at security.stackexchange.com.
I also wouldn't store large amounts of data in NSUserDefaults. It also is not intended to be used that way. Data should be stored in a file in one of the relevant directories defined under NSSearchPathDirectory
, or else in iCloud.
It's a matter of performance. All of the code for working with both keychain and user defaults is based on the assumption only a small amount of data will be there. It's very fast for small amounts of data, but larger amounts will wast memory and cpu cycles/battery power. And in the case of keychain, you are also wasting the user's LTE bandwidth, since every change will be sent over the internet to every device they own.
I don't think Apple's app review team actively enforces this stuff, but it would technically violate the rules to use the API for anything other than it's intended purpose.