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?
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.
[attributeDict setObject:(__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly forKey:(__bridge id)kSecAttrAccessible];