Saving in KeyChainItemWrapper crashes for password

2019-03-11 04:21发布

问题:

Apple has provided KeyChainItemWrapper class in their GenericKeyChain sample code. There is an ARC'ed solution here on SO, which I am trying to follow: wrapper to store in the KeyChain on iOS.

The usage of the wrapper is like this:

KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@"F11-email-auth" accessGroup:nil];
[keychain setObject:[emailTextfield text] forKey:(__bridge id)(kSecMatchEmailAddressIfPresent)];
[keychain setObject:[passwordTextfield text] forKey:(__bridge id)(kSecClassGenericPassword)];

the line with email text field is accepted. But the second line with the password crashes with the following exception.

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Couldn't add the Keychain Item.'
*** First throw call stack:
(
    0   CoreFoundation                      0x01b445e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x018c78b6 objc_exception_throw + 44
    2   CoreFoundation                      0x01b44448 +[NSException raise:format:arguments:] + 136
    3   Foundation                          0x014a823e -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
    4   Feeltracker                         0x000053b3 -[KeychainItemWrapper writeToKeychain] + 899
    5   Feeltracker                         0x00004700 -[KeychainItemWrapper setObject:forKey:] + 272
    6   Feeltracker                         0x000092d6 -[FTLoginViewController connectToAccount:] + 374
    7   libobjc.A.dylib                     0x018d9874 -

What could be the reason? I wonder if it has anything to do with the constants I am using.

UPDATE:

Thanks to rmaddy's help:

This is the bit that seems to throw the error:

// No previous item found; add the new one.
result = SecItemAdd((__bridge CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData], NULL);
NSAssert( result == noErr, @"Couldn't add the Keychain Item." );

result is at -50. The SecItemAdd is a lib method. As I was expecting, this is somehow related to the KeyChain handling directly...

keychainItemData contains:

回答1:

I couldn't get this Apple example for Keychain wrapper work any longer. Luckily further research into this matter revealed this solution, which worked for me.

Beware the original answer to the solution is not ARC'ed, however someone was so kind to create an ARC'ed version on Github. I used that one and works like a charm.

It is a wrapper around the keychain, that works even simpler than the original one.

Hope this helps others with a similar problem.



回答2:

I had the same error when running the App on the Simulator, but it worked perfectly on the device.

In order to fix the problem with the simulator I had to turn on "Share keychain entitlement".

Share keychain entitlement