嗯,這個問題的答案是有點棘手.... 顯然,有關於這件事情的蘋果已知的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;
}