This question discusses encrypting data on the iPhone using the crypt() function. As an alternative, is there a keychain on the iPhone and if so, what code would I use to access it in order to store login details and then retrieve them for us in an application?
7 Answers
One other thing to note: the keychain APIs don't work in the simulator when using older versions (2.x, 3.x) of the iPhone SDK. This could save you a lot of frustration when testing!

- 16,255
- 2
- 41
- 60

- 85,404
- 22
- 176
- 172
-
This has been fixed for a while now. It does work for me in the simulator. – bartvdpoel Feb 17 '11 at 16:35
-
Yes, it now works in the sim. I believe it was fixed in a 3.x release. – Ben Gottlieb Feb 17 '11 at 18:51
There is a keychain you can use - for code, the best bet is to check out the GenericKeychain sample application from Apple:

- 2,951
- 3
- 28
- 56

- 1,422
- 10
- 8
I really like Buzz Anderson's Keychain abstraction layer and I eagerly await Jens Alfke's MYCrypto to reach a usable state. The latter does a competent job of allowing use on Mac OS X and the iPhone using the same code, though its features only mimic a small subset of the Keychain's.

- 6,370
- 5
- 37
- 43
Here is what i use to store Key/Value pairs in the keychain. Make sure to add Security.framework to your project
#import <Security/Security.h>
// -------------------------------------------------------------------------
-(NSString *)getSecureValueForKey:(NSString *)key {
/*
Return a value from the keychain
*/
// Retrieve a value from the keychain
NSDictionary *result;
NSArray *keys = [[[NSArray alloc] initWithObjects: (NSString *) kSecClass, kSecAttrAccount, kSecReturnAttributes, nil] autorelease];
NSArray *objects = [[[NSArray alloc] initWithObjects: (NSString *) kSecClassGenericPassword, key, kCFBooleanTrue, nil] autorelease];
NSDictionary *query = [[NSDictionary alloc] initWithObjects: objects forKeys: keys];
// Check if the value was found
OSStatus status = SecItemCopyMatching((CFDictionaryRef) query, (CFTypeRef *) &result);
[query release];
if (status != noErr) {
// Value not found
return nil;
} else {
// Value was found so return it
NSString *value = (NSString *) [result objectForKey: (NSString *) kSecAttrGeneric];
return value;
}
}
// -------------------------------------------------------------------------
-(bool)storeSecureValue:(NSString *)value forKey:(NSString *)key {
/*
Store a value in the keychain
*/
// Get the existing value for the key
NSString *existingValue = [self getSecureValueForKey:key];
// Check if a value already exists for this key
OSStatus status;
if (existingValue) {
// Value already exists, so update it
NSArray *keys = [[[NSArray alloc] initWithObjects: (NSString *) kSecClass, kSecAttrAccount, nil] autorelease];
NSArray *objects = [[[NSArray alloc] initWithObjects: (NSString *) kSecClassGenericPassword, key, nil] autorelease];
NSDictionary *query = [[[NSDictionary alloc] initWithObjects: objects forKeys: keys] autorelease];
status = SecItemUpdate((CFDictionaryRef) query, (CFDictionaryRef) [NSDictionary dictionaryWithObject:value forKey: (NSString *) kSecAttrGeneric]);
} else {
// Value does not exist, so add it
NSArray *keys = [[[NSArray alloc] initWithObjects: (NSString *) kSecClass, kSecAttrAccount, kSecAttrGeneric, nil] autorelease];
NSArray *objects = [[[NSArray alloc] initWithObjects: (NSString *) kSecClassGenericPassword, key, value, nil] autorelease];
NSDictionary *query = [[[NSDictionary alloc] initWithObjects: objects forKeys: keys] autorelease];
status = SecItemAdd((CFDictionaryRef) query, NULL);
}
// Check if the value was stored
if (status != noErr) {
// Value was not stored
return false;
} else {
// Value was stored
return true;
}
}
It is worth noting that these key/values will not get deleted if the user deletes your app. If a user deletes your app, then reinstalls it, the key/values will still be accessible.

- 8,101
- 3
- 51
- 65
-
-
2There is a bug in Selector getSecureValueForKey: When you return the value, it is already released. It is released by "[result release];" – Mhh Lecker Feb 03 '12 at 16:03
-
I modified to be C functions instead of Objective-C methods. In my case, I would like to make this functionality available to any object on my app, and the functionality itself doesn't seem to require any kind of persistent storage (ivars). But otherwise, great snippet! – Nicolas Miari Jun 25 '12 at 08:54
Also remember that when generating an AppID, if you want more than one application to access the same Keychain information, you have to generate a wild card AppID (#####.com.prefix.*)...

- 622
- 4
- 7
With the latest version 1.2 of the GenericKeychain sample Apple provides a keychain wrapper that also runs on the iPhone Simulator. Check out at this article for details: http://dev-metal.blogspot.com/2010/08/howto-use-keychain-in-iphone-sdk-to.html

- 57
- 1
Here is one more good wrapper class from Mr.Granoff https://github.com/granoff/Lockbox Thanks

- 2,866
- 1
- 16
- 20