如何在OS X中成功删除钥匙串中的项目?这是我到目前为止所做的,但它在SecItemDelete
电话中失败了。我是否需要在查询字典中指定一些其他属性?我可以通过执行类似的操作成功地将键值对插入到钥匙串中。
#define DELETE_SIZE 3
bool delete_key_keychain( const char *cKeyValue, SecKeychainRef keychain) {
if ( !keychain)
return false;
// Convert to CFString.
CFStringRef keyValue = CFStringCreateWithCString( NULL, cKeyValue, kCFStringEncodingUTF8);
if ( !keyValue)
return false;
// Specify query parameters.
const void *keys[DELETE_SIZE] = {
kSecClass,
kSecUseKeychain,
kSecAttrAccount
};
const void *values[DELETE_SIZE] = {
kSecClassGenericPassword,
keychain,
keyValue
};
// Create query.
CFDictionaryRef query = CFDictionaryCreate( NULL, keys, values, GET_SIZE, NULL, NULL);
if ( !query) {
CFRelease( keyValue);
return false;
}
// Run query.
OSStatus status = SecItemDelete( query);
CFRelease( query);
CFRelease( keyValue);
return status == errSecSuccess;
}
更新:根据此link,我需要在查询中设置kSecAttrService
属性。因此,我开始使用SecKeychainFindGenericPassword
和SecKeychainItemDelete
。这将成功删除密码,但随后为同一帐户添加不同的密码可能会导致崩溃。因此,我已经开始使用SecKeychainItemModifyAttributesAndData
修改密码而不删除密码。我相信这种不稳定性可能是由于API执行的缓存。
答案 0 :(得分:0)
过去,我使用此功能从我的Mac OS钥匙串中删除特定的公钥/私钥对项
// remove keypair from keychain
- (BOOL)deleteKeysFromKeychain {
OSStatus sanityCheck1 = noErr;
OSStatus sanityCheck2 = noErr;
NSMutableDictionary * queryPublicKey = [[NSMutableDictionary alloc] init];
NSMutableDictionary * queryPrivateKey = [[NSMutableDictionary alloc] init];
// Set the public key query dictionary.
[queryPublicKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[queryPublicKey setObject:self.myPublicTag forKey:(__bridge id)kSecAttrApplicationTag];
[queryPublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
// Set the private key query dictionary.
[queryPrivateKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[queryPrivateKey setObject:self.myPrivateTag forKey:(__bridge id)kSecAttrApplicationTag];
[queryPrivateKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
// Delete the private key.
sanityCheck1 = SecItemDelete((__bridge CFDictionaryRef)queryPrivateKey);
// Delete the public key.
sanityCheck2 = SecItemDelete((__bridge CFDictionaryRef)queryPublicKey);
@autoreleasepool {
queryPrivateKey = nil;
queryPublicKey = nil;
}
return ( sanityCheck1 == sanityCheck2 && sanityCheck2 == noErr ? YES : NO );
}
myPublicTag类似'com.yourAppName.publickey'
myPrivateTag类似'com.yourAppName.privatekey'
也许这可能有用