嗯,这个问题的答案是有点棘手.... 显然,有关于这件事情的苹果已知的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;
}