Can the keychain be used like a NSUserDefaults on steroids for storing NSData?

cocoa, ios, keychain, keychainitemwrapper

Solution

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.

Problem

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?

Original source