2013-10-24 70 views
3

我试图通过钥匙串API从钥匙串中删除配对私钥的证书。我可以轻松删除证书,但私钥总是被留下。我怎样才能从钥匙串中删除它? 我已经尝试了几种方法,但即使使用SecKeyRef,一旦我运行SecItemDelete(例如),该函数将返回errSecSuccess的状态,但密钥仍然存在于钥匙串中!以编程方式从钥匙串中删除私钥(与证书匹配)

任何帮助,非常感谢,如果有任何示例代码,请发布它。 Errrrr!这是如此令人沮丧...

谢谢..

回答

0

嗯,这个问题的答案是有点棘手.... 显然,有关于这件事情的苹果已知的bug,没有已知的解决方法(这是取自苹果的DTS响应)。

如果有一个ACL限制对其的访问并允许一个和一个应用程序访问密钥,则可以删除私钥。 所以,从理论上讲,可以更改访问对象并限制ACL列表,然后删除它。

但是....不幸的是,试图操纵身份的访问对象有相同的ACL时手动更改它通过钥匙串访问不表现为很好的...

如果你设法万一限制那么剩下的是很容易的:

因此,这里是以防万一有人代码段发现它有用:

OSStatus status  = errSecSuccess; 
CFTypeRef identityRef = NULL; 
CFStringRef certLabel = NULL; 

const char *certLabelString = "Some string identifying your certificate"; 
certLabel = CFStringCreateWithCString(NULL, certLabelString, kCFStringEncodingUTF8); 

const void *keys[] = { kSecClass, kSecAttrLabel, kSecReturnRef }; 
const void *values[] = { kSecClassIdentity, certLabel, kCFBooleanTrue }; 
CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values, 3, NULL, NULL); 

// First we extract the identity out of the keychain 
status = SecItemCopyMatching(query, &identityRef); 
if (status != errSecSuccess) 
{ 
    s_log(SecCopyErrorMessageString(status, NULL)); 
    CFRelease(certLabel); 
    CFRelease(query); 
    if (identityRef) 
     CFRelease(identityRef); 

    return -1; 
} 

CFRelease(certLabel); 
CFRelease(query); 

// We have obtained the identity so we can delete it 
CFArrayRef itemList = CFArrayCreate(NULL, &identityRef, 1, NULL); 
const void *keys2[] = { kSecClass, kSecMatchItemList, kSecMatchLimit }; 
const void *values2[] = { kSecClassIdentity, itemList, kSecMatchLimitAll }; 

CFDictionaryRef dict = CFDictionaryCreate(NULL, keys2, values2, 3, NULL, NULL); 
status = SecItemDelete(dict); 

if (status != errSecSuccess) { 
    s_log(SecCopyErrorMessageString(status, NULL)); 
    CFRelease(dict); 
    CFRelease(itemList); 
    CFRelease(identityRef); 
    return -2; 
}