【问题标题】:Objective-C The specified item already exists in the keychain [iOS]Objective-C 指定项已存在于钥匙串中[iOS]
【发布时间】:2016-10-24 12:00:59
【问题描述】:

我不确定为什么这段代码会失败。我总是收到 errSecDuplicateItem

首先我尝试调用 SecPKCS12Import。

    CFDataRef inId = (CFDataRef)certToImport_;   
    OSStatus securityError = errSecSuccess;
    CFStringRef pw = (CFStringRef)password;
    const void *keys[] = { kSecImportExportPassphrase };
    const void *values[] = { pw };

    CFDictionaryRef myDict = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);   
    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);

    securityError = SecPKCS12Import(inId, myDict, &items);

    if (securityError == errSecSuccess) {

        securityError = [self addIdentityToKeychain:items];
        if (securityError == errSecSuccess)
        {
            securityError = [self addRootCaToKeychain:items];
            ....

所以从上面的代码中,我调用 addIdentityToKeychain 返回成功。

- (OSStatus)addIdentityToKeychain:(CFArrayRef)importDict
{
    CFDictionaryRef myId = CFArrayGetValueAtIndex(importDict, 0);

    const void *tempId = NULL;
    tempId = CFDictionaryGetValue(myId,kSecImportItemIdentity);
    SecIdentityRef secId = (SecIdentityRef)tempId;

    SecCertificateRef certRef;

    OSStatus securityError = SecIdentityCopyCertificate(secId, &certRef);

    if (securityError == errSecSuccess) {
        uniqueLabel_ = [[NSString alloc] initWithString:[self GetUniqueLabel:certRef]];
        NSMutableDictionary *secIdentityParams = [[NSMutableDictionary alloc] init];    
        [secIdentityParams setObject:(id)secId forKey:(id)kSecValueRef];
        securityError = SecItemAdd((CFDictionaryRef) secIdentityParams, NULL);
        [secIdentityParams release];
    }
    return securityError;
}

但是当我最终尝试调用 addRootCaToKeychain 失败时,抱怨我们有重复的条目。它第一次失败,随机证书在任何情况下都无法导入。

 - (OSStatus)addRootCaToKeychain:(CFArrayRef)importDict
    {
        OSStatus securityError = errSecSuccess;

        CFDictionaryRef myId = CFArrayGetValueAtIndex(importDict, 0);
        NSArray *certs = (NSArray*)CFDictionaryGetValue(myId, kSecImportItemCertChain);
        CFIndex cnt = [certs count];
        if (cnt)
        {
            CFIndex i = 0;
            while ((i < cnt)) {
                SecCertificateRef certRef = (SecCertificateRef)[certs objectAtIndex:i];
                NSMutableDictionary *secCertParams = [[NSMutableDictionary alloc] init];    
                [secCertParams setObject:(id)certRef forKey:(id)kSecValueRef];
                [secCertParams setObject:(id)uniqueLabel_ forKey:(id)kSecAttrLabel];
                securityError = SecItemAdd((CFDictionaryRef) secCertParams, NULL);
                [secCertParams release];
                // if we get something other than success or duplicate, we will quit right here and report the error.  
                if ((securityError != errSecSuccess) && (securityError != errSecDuplicateItem)) {
                    return securityError;
                }
                i++;
            }
        }
        return securityError;
    }

代码有什么问题?任何想法?

【问题讨论】:

    标签: ios objective-c iphone certificate


    【解决方案1】:

    addRootCaToKeychain 中添加SecItemAdd 之前检查项目是否已经存在,如下所示:

    //adding access key 
    [secCertParams setObject:(id)key forKey:(id) kSecValueRef];
    [secCertParams setObject:(id)uniqueLabel_ forKey:(id) kSecAttrLabel];
    
    //check and removing item if it exists 
    SecItemDelete((CFDictionaryRef) secCertParams);
    
    //setting data (private key) 
    [secCertParams setObject:(id) secCertParams forKey:(id)kSecValueData];
    

    也可以在这里查看答案以获取更多详细信息:https://stackoverflow.com/a/12387678/5575752

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      • 2018-08-29
      • 1970-01-01
      • 2020-03-23
      • 1970-01-01
      • 2014-08-16
      相关资源
      最近更新 更多