Simple IPhone Keychain Access

Source: Internet
Author: User

Simple IPhone Keychain Access

Mar th, 9:14 pm

The keychain is about the-the-place-an-iPhone application can safely store data that'll be preserved across a re-i Nstallation of the application. Each IPhone application gets its own set of keychain items which is backed up whenever the user backs up the device via I Tunes. The backup data is encrypted, as part of the backup so, it remains secure even if somebody gets access to the backup Da Ta. This makes it very attractive to store sensitive data such as passwords, license keys, etc.

The only problem are that accessing the keychain services are complicated and even the Generickeychain example code is hard To follow. I hate to include the cut and pasted code into my application, especially when I does not understand it. Instead I has gone back to basics to build up a simple IPhone keychain Access example that does just what I want and not Much more.

In fact all I really want to being able to does is securely store a password string for my application and being able to retrieve It a later date.

Getting Started

A couple of housekeeping items to get started:

    • Add the "security.framework" framework to your IPhone application
    • Include the header file <Security/Security.h>

Note that the security framework was a good old fashioned C-framework so no objective-c style methods calls. Also it would only work on the device is not in the the IPhone Simulator.

The Basic Search Dictionary

All of the calls to the keychain services make use of a dictionary to define the attributes of the keychain item you want To find, create, update or delete. So the first thing we'll do are define a function to allocate and construct this dictionary for us:

static NSString *serviceName = @"com.mycompany.myAppServiceName";- (NSMutableDictionary *)newSearchDictionary:(NSString *)identifier {  NSMutableDictionary *searchDictionary = [[NSMutableDictionary alloc] init];    [searchDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];  NSData *encodedIdentifier = [identifier dataUsingEncoding:NSUTF8StringEncoding];  [searchDictionary setObject:encodedIdentifier forKey:(id)kSecAttrGeneric];  [searchDictionary setObject:encodedIdentifier forKey:(id)kSecAttrAccount];  [searchDictionary setObject:serviceName forKey:(id)kSecAttrService];  return searchDictionary;}

The dictionary contains three items. The first with key Ksecclass defines the class of the keychain item we'll be a dealing with. I want to store a password with the keychain so I use the value of Ksecclassgenericpassword for the value.

The second item in the dictionary with key ksecattrgeneric are what we'll use to identify the keychain item. It can be any value we choose such as "Password" or "LicenseKey", etc. To being clear this is not the actual value of the password just a label we'll attach to this keychain item so we can find It later. In theory our application could store a number of passwords in the keychain so we need to having a-to-identify this part Icular one from the others. The identifier have to being encoded before being added to the dictionary

The combination of the final attributes Ksecattraccount and ksecattrservice should be set to Somethi Ng unique for this keychain. The example I set the service name to a static string and reuse the identifier as the account name.

You can use the multiple attributes for a given class of item. Some of the other attributes so we could also use for the Ksecclassgenericpassword item include a account name , description, etc. However by using just a single attribute we can simplify the rest of the code.

Searching the Keychain

To find out if our password already exists in the keychain (and what the value of the password are) we use the SECITEMC Opymatching function. But first we add a couple the extra items to our basic Search dictionary:

- (NSData *)searchKeychainCopyMatching:(NSString *)identifier {  NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier];  // Add search attributes  [searchDictionary setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];  // Add search return types  [searchDictionary setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];  NSData *result = nil;  OSStatus status = SecItemCopyMatching((CFDictionaryRef)searchDictionary,                                        (CFTypeRef *)&result);  [searchDictionary release];  return result;}

The first attribute we add to the dictionary are to limit the number of search results that get returned. We is looking for a, entry so we set the attribute ksecmatchlimit to ksecmatchlimitone.

The next attribute determines how the result is returned. Since in our simple case we is expecting only a single attribute to be returned (the password) we can set the attribute C0>ksecreturndata to kcfbooleantrue. This means we'll get a nsdata reference back to that we can access directly.

If we were storing and searching for a keychain item with multiple attributes (for example if we were storing an account n Ame and password in the same keychain item) we would need to add the attribute ksecreturnattributes and the Resul T would be a dictionary of attributes.

Now with the search dictionary set up we call the secitemcopymatching function And if our item exists in the KEYC Hain the value of the password is returned to the NSData block. To get the actual decoded string of could do something like:

  NSData *passwordData = [self searchKeychainCopyMatching:@"Password"];  if (passwordData) {    NSString *password = [[NSString alloc] initWithData:passwordData                                           encoding:NSUTF8StringEncoding];    [passwordData release];  }
Creating an item in the Keychain

Adding an item is almost the same as the previous examples except, the we need to set the value of the password we want to Store.

- (BOOL)createKeychainValue:(NSString *)password forIdentifier:(NSString *)identifier {  NSMutableDictionary *dictionary = [self newSearchDictionary:identifier];  NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];  [dictionary setObject:passwordData forKey:(id)kSecValueData];  OSStatus status = SecItemAdd((CFDictionaryRef)dictionary, NULL);  [dictionary release];  if (status == errSecSuccess) {    return YES;  }  return NO;}

To set the value of the password we add the attribute Ksecvaluedata to our search dictionary making sure we encod E The string and then call secitemadd passing the dictionary as the first argument. If the item already exists in the keychain this would fail.

Updating a Keychain item

Updating a keychain is similar to adding an item except a separate dictionary are used to contain the attributes Updated. Since in we have updating a single attribute (the password)

- (BOOL)updateKeychainValue:(NSString *)password forIdentifier:(NSString *)identifier {  NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier];  NSMutableDictionary *updateDictionary = [[NSMutableDictionary alloc] init];  NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];  [updateDictionary setObject:passwordData forKey:(id)kSecValueData];  OSStatus status = SecItemUpdate((CFDictionaryRef)searchDictionary,                                  (CFDictionaryRef)updateDictionary);  [searchDictionary release];  [updateDictionary release];  if (status == errSecSuccess) {    return YES;  }  return NO;}
Deleting an item from the keychain

The final (and easiest) operation is to delete a item from the keychain using the secitemdelete function and our Usual Search dictionary:

- (void)deleteKeychainValue:(NSString *)identifier {  NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier];  SecItemDelete((CFDictionaryRef)searchDictionary);  [searchDictionary release];}

Simple IPhone Keychain Access

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.