SecItemAdd and SecItemCopyMatching returns error c

2019-01-04 05:50发布

Sometimes when I run an application on device from Xcode I would try to access the keychain but fail due to error -34018. This doesn't match any of the documented keychain error codes and can't be consistently reproduced. (happens maybe 30% of the time, and it's not clear to me why it happens). What makes debugging this problem very difficult is the total lack of documentation. Any idea what causes this and how to fix it? I'm using Xcode 5 and running iOS 7.0.4 on device.

There is an open issue about this here: https://github.com/soffes/sskeychain/issues/52

EDIT: Adding keychain access code per request

I'm using the SSKeychain library for interfacing with keychain. Here's the snippet.

#define SERVICE @"default"

@implementation SSKeychain (EXT)

+ (void)setValue:(NSString *)value forKey:(NSString *)key {
    NSError *error = nil;
    BOOL success = NO;
    if (value) {
        success = [self setPassword:value forService:SERVICE account:key error:&error];
    } else {
        success = [self deletePasswordForService:SERVICE account:key error:&error];
    }
    NSAssert(success, @"Unable to set keychain value %@ for key %@ error %@", value, key, error);
    if (!success) {
        LogError(@"Unable to set value to keychain %@", error);
    }
    LogTrace(@"Will set keychain account %@. is to nil? %d", key, value == nil);
    if (value == nil)
        LogWarn(@"Setting keychain %@ to nil!!!", key);
}

+ (NSString *)valueForKey:(NSString *)key {
    NSError *error = nil;
    NSString *value = [self passwordForService:SERVICE account:key error:&error];
    if (error && error.code != errSecItemNotFound) {
        NSAssert(!error, @"Unable to retrieve keychain value for key %@ error %@", key, error);
        LogError(@"Unable to retrieve keychain value for key %@ error %@", key, error);
    }
    return value;
}

+ (BOOL)removeAllValues {
    LogInfo(@"Completely Reseting Keychain");
    return [[self accountsForService:SERVICE] all:^BOOL(NSDictionary *accountInfo) {
        return [self deletePasswordForService:SERVICE account:accountInfo[@"acct"]];
    }];
}

@end

Vast majority of the time it's just fine. Sometimes I'll hit the assertion failures where I'm unable to either write to or read from keychain, causing critical assertion failure.

19条回答
一夜七次
2楼-- · 2019-01-04 05:52

I got bitten by this, too and had no success with any of the other workarounds. I then cleaned up my provisioning profiles on the devices itself by deleting all of them related to my app as well as all the wildcard profiles (this seems to be the point). To do this, go to the "Devices" Window in Xcode and right-click your (connected) phone:

Click on "Show provisioning profiles" and delete the related ones, and especially the team profiles:

including the ones with the asterisk. After reinstallation the app, everything went back to normal.

查看更多
Juvenile、少年°
3楼-- · 2019-01-04 05:54

(this is not a direct answer to the OP's question, but might help others)

Started getting the keychain error -34018 consistently in simulator after updating Xcode from version 7.3.1 to 8.0.

Following this tip from daidai's answer,

Some instances of the problem are caused by incorrect app signing. You can easily distinguish this case because the problem is 100% reproducible.

it was discovered that Provisioning Profile had somehow been set to None in the Signing sections of the target.

However, setting the Provisioning Profile fields to valid values was not sufficient to resolve the issue in this case.

Further investigation showed that the Push Notifications entitlement also displayed an error. It said the "Add the Push Notifications feature to your App ID." step was completed, but step "Add the Push Notifications entitlement to your entitlements file" was not.

After pressing "Fix Issue" to fix the Push Notification issue, the keychain error was resolved.

For this particular target, the "Keychain Sharing" entitlement had already been turned on at some previous time. Turning it off has not caused the keychain error to reappear so far, so its not clear whether it is necessary in this case.

查看更多
Rolldiameter
4楼-- · 2019-01-04 05:55

I was getting -34018 error in my app (iOS 8.4) very rarely. After some investigation I've found that this issue occurs when the app requests data from keychain too often.
For example, in my situation it was two read requests for one specific key at the same time from different application modules.
To fix that I've just added caching this value in memory

查看更多
成全新的幸福
5楼-- · 2019-01-04 05:56

After inspecting the source code. I have noticed that the keychain features are accessed through a security daemon that runs in its own process (separated from the app process).

Your app and the securityd process 'talk' together through a technology called XPC.

If necessary, the securityd is launched via the well-known launchd command by XPC. You can probably check that the daemon is running in the Activity Monitor App (if running in Simulator of course) and that its parent process is launchd.

My guess here is that it is possible that for any unknown reason the security daemon fails to start or do it too slowly and is not ready when you try to use it.

Maybe you could think on how to pre-launch the daemon.

I apologize for not being more precise. I hope it could help you to go a bite further in your investigations.

查看更多
Animai°情兽
6楼-- · 2019-01-04 05:57

I was having the same problem, out of the blue, running on a test device with Xcode 6.2, iPhone 6, iOS 8.3. To be clear, this was not experienced while running Xcode tests, but rather while running the actual app on my device. In the simulator it was fine, and running on the app itself it had been perfectly fine until recently.

I tried all of the suggestions I could find here, such as removing the provisioning profiles on my device (I removed ALL of them), temporarily enabling the Keychain Sharing capability in my project (even though we don't really need that), making sure my development account in Xcode was totally refreshed with all of the certificates and provisioning profiles, etc. Nothing helped.

Then I temporarily changed the accessibility level from kSecAttrAccessibleAfterFirstUnlock to kSecAttrAccessibleAlwaysThisDeviceOnly, ran the app, and it worked fine and was able to write to the Keychain. Then I changed it back to kSecAttrAccessibleAfterFirstUnlock, and the problem seems to have gone away "permanently."

查看更多
唯我独甜
7楼-- · 2019-01-04 05:57

Just got bitten by this bug on Xcode 8 Beta 3. Turning on Keychain Sharing seems to be the only solution.

查看更多
登录 后发表回答