2015-10-16 214 views
2

上SecPKCS12Import的documentation规定如下:为什么SecPKCS12Import会自动将SecIdentities添加到钥匙串?

[...]然后,您可以使用Keychain服务API(参见Keychain服务 参考)把身份和相关的证书,在 钥匙串。

这意味着在“items”参数(该函数的第三个参数)中返回的项目不应该自动添加到钥匙串中。但是,我发现这些项目在使用该功能时会自动添加到钥匙串中。如果我尝试使用SecItemAdd添加它们,我会得到errSecDuplicateItem。

这是一个错误还是应该这样?为什么会自动添加项目?

下面是一些示例代码:

NSDictionary *options = [[NSDictionary alloc] initWithObjectsAndKeys:@"password", (id)kSecImportExportPassphrase, nil]; 
CFArrayRef items_ = NULL; 
OSStatus ret = SecPKCS12Import((CFDataRef)pkcs12data /* get this from somewhere … */, (CFDictionaryRef)options, &items_); 

如果您使用的代码,然后打开钥匙串访问,您将看到证书和私钥已被添加到钥匙串。

Regards, David。

回答

1

好像苹果的文档可能会过时该链接(SecPKCS12Import),因为这个环节https://developer.apple.com/library/ios/qa/qa1745/_index.html提到,“在读一PKCS#12格式的斑点,然后导入Blob的内容到应用程序的钥匙扣使用功能SecPKCS12Import ...“

按照文档修订日期,QA1745比证书,密钥和信任服务参考更新。

+0

您可能要问了一个新问题,而不是在现有的一个张贴一个答案。 – JAL

+0

编辑删除末尾的问题 – satishmaha

-1

SecPKCS12Import不会将项目添加到钥匙串中。但是,它会在钥匙串中查看导入的项目是否已经存在。如果它找到现有项目,将返回SecIdentityRef (SecCertificateRef and SecKeyRef)。这就是为什么在致电SecPKCS12Import后致电SecItemAdd时您可以获得errSecDuplicateItem

调试时,您可能希望使用这样的代码在你的钥匙链,除去一切:

void _EraseKeychain() 
{ 
    NSMutableArray *toDelete = [NSMutableArray array]; 
    NSArray *classes = @[(__bridge id)kSecClassCertificate, 
         (__bridge id)kSecClassKey, 
         (__bridge id)kSecClassIdentity, 
         (__bridge id)kSecClassInternetPassword, 
         (__bridge id)kSecClassGenericPassword]; 
    NSMutableDictionary *query = [NSMutableDictionary dictionary]; 
    query[(id)kSecClass] = (__bridge id)kSecClassIdentity; 
    query[(id)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll; 
    query[(id)kSecReturnPersistentRef] = @YES; 
    id class; 
    for(class in classes) 
    { 
     query[(__bridge id)kSecClass] = class; 
     CFTypeRef items = nil; 
     OSStatus result = SecItemCopyMatching((__bridge CFDictionaryRef)query, &items); 
     if(result == errSecSuccess) 
     { 
      [toDelete addObjectsFromArray:(__bridge NSArray*)items]; 
      CFRelease(items); 
     } 
    } 
    id deleteRef; 
    for(deleteRef in toDelete) 
    { 
     NSString *objectKind = @"unknown"; 
     if(CFGetTypeID(deleteRef) == CFDataGetTypeID()) 
     { 
      objectKind = [[NSString alloc] initWithUTF8String:(char *)[(__bridge NSData*)deleteRef bytes]]; 
     } 
     NSDictionary *delRequest = @{(id)kSecValuePersistentRef:deleteRef}; 
     OSStatus deleteResult = SecItemDelete((__bridge CFDictionaryRef)delRequest); 
     if(deleteResult == errSecSuccess) 
      NSLog(@"Deleted item(%@) with persistent ref %@", objectKind, deleteRef); 
     else if(deleteResult == errSecItemNotFound) 
      NSLog(@"Already deleted item(%@) with persistent ref %@", objectKind, deleteRef); 
     else 
      NSLog(@"Can't delete keychain item(%@) with persistent ref %@", objectKind, deleteRef); 
    } 
} 
+0

'SecIdentityRef'是证书/密钥对的别名。如果删除它,您将删除与之匹配的证书和密钥。如果你删除了证书和密钥,那么'SecIdentityRef'将失效。 –

+0

您可以在https://opensource.apple.com/source/libsecurity_keychain/libsecurity_keychain-55050.9/lib/SecImportExport.c中清楚地看到SecPKCS12Import确实会将其导入钥匙串中,并且事实上在使用此功能时无法阻止它功能。 –

相关问题