4
votes

I am developing an application with keychain implementation . i am able to create & Save data into keychain . I am using the Keychain Wrapper classes provided By Apple.

According to requirement , I have to implement best possible Security in the KeyChain (The security team pointed out lapses , such as it's accessibility on Jail-broken devices).

Could Someone give me direction?

2

2 Answers

7
votes

I had also Implemented keychain in application long Back using the same Wrapper you cited , but , of course with a lot of modifications.

Basically Keychain is quite secure .According to Apple , it's an encrypted container that holds secure information for multiple applications ,which means that when the keychain is locked, no one can access its protected contents .

In iOS , only the application creating the keychain can access it. According to Apple's documentation , iOS can choose to Memory-Cache or Disk Cache it.

But from iOS 4.xx++ , it's only disk-cached(dunno why) , thus always creating a sqlite DB , where all the data in the keychain are stored corresponding to a particular Identifier.

The Sqlite DB Can be Hacked on rooted or Jail-broken devices.

To Secure the Keychain

1 Add the security keyword "kSecAttrAccessibleWhenUnlockedThisDeviceOnly" while adding or
updating the data in keychain on the methods "SecItemUpdate" & "SecItemAdd".

Something like :-

- (void)writeToKeychain
{
    NSDictionary *attributes = NULL;
    NSMutableDictionary *updateItem = NULL;
    OSStatus result;

    if (SecItemCopyMatching((CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&attributes) == noErr)
    {
        updateItem = [NSMutableDictionary dictionaryWithDictionary:attributes];

        [updateItem setObject:[genericPasswordQuery objectForKey:(id)kSecClass] forKey:(id)kSecClass];

        NSMutableDictionary *tempCheck = [self dictionaryToSecItemFormat:keychainItemData];
        [tempCheck removeObjectForKey:(id)kSecClass];

#if TARGET_IPHONE_SIMULATOR
        [tempCheck removeObjectForKey:(id)kSecAttrAccessGroup];
#endif

        [updateItem setObject:(id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly forKey:(id)kSecAttrAccessible];
        result = SecItemUpdate((CFDictionaryRef)updateItem, (CFDictionaryRef)tempCheck);
        NSAssert( result == noErr, @"Couldn't update the Keychain Item." );
        CFRelease(attributes);
    }
    else
    {
        [keychainItemData setObject:(id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly forKey:(id)kSecAttrAccessible];
        result = SecItemAdd((CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData], NULL);
        NSAssert( result == noErr, @"Couldn't add the Keychain Item." );
    }
}

2 Encrypt the data before Adding to the Keychain .I used AES-128 Encryption. Also ensure that the key used for Encryption is RSA key.(sent by SSL Web Service ).

NOTE :-The Keychain Data is stored in the /private/var/Keychains/keychain-2.db file on the iPhone.

Hope it helps you.

0
votes
    [attributeDict setObject:(__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly forKey:(__bridge id)kSecAttrAccessible];