用SecItemDelete删除密码报错:
errSecItemNotFound = -25300, /* The specified item could not be found in the keychain. */
用SecItemAdd存储新的密码报错:
errSecDuplicateItem = -25299, /* The specified item already exists in the keychain. */
删除keychain数据代码:
+ (BOOL)deleteSharedKeyInKeychain:(NSString *)tag {
if (!tag) {
return NO;
}
// 删除之前的共享密钥(如果存在)
NSDictionary *attributes = @{
(id)kSecClass: (id)kSecClassGenericPassword, // 数据类型
(id)kSecAttrAccount: tag, // 唯一标识符
(id)kSecAttrService:tag,
(id)kSecAttrAccessible: (id)kSecAttrAccessibleAlways // 访问权限
};
OSStatus status = SecItemDelete((__bridge CFDictionaryRef)attributes); // 清理旧密钥
return status == noErr;
// VVLog(@"deleteSharedKeyInKeychain -- deviceid:%@", tag);
}
原因分析: kSecClassGenericPassword的唯一密钥由以下几部分组成:
kSecAttrAccount
kSecAttrService
要检查其是否存在,只需使用这些属性(包括kSecReturnAttributes标志)查询密钥链存储。
包含kSecAttrLabel和kSecAttrAccessible将排除具有相同唯一键但具有不同属性的任何现有项。
确认其(不)存在后,添加附加属性并添加或更新。
因为在此之前我的存储属性是 kSecAttrAccessibleWhenUnlocked,后面改为kSecAttrAccessibleAlways,所以如果设置删除代码里面的属性为kSecAttrAccessibleAlways就会报错errSecItemNotFound找不到对应kSecAttrAccessibleWhenUnlocked的密码,所以正确的删除代码:
+ (BOOL)deleteSharedKeyInKeychain:(NSString *)tag {
if (!tag) {
return NO;
}
// 删除之前的共享密钥(如果存在)
NSDictionary *attributes = @{
(id)kSecClass: (id)kSecClassGenericPassword, // 数据类型
(id)kSecAttrAccount: tag, // 唯一标识符
(id)kSecAttrService:tag
};
OSStatus status = SecItemDelete((__bridge CFDictionaryRef)attributes); // 清理旧密钥
return status == noErr;
// VVLog(@"deleteSharedKeyInKeychain -- deviceid:%@", tag);
}