使用secItemUpdate错误代码-50在iOS中更新kSecValueData
我在这里不知所措,我创建了一个keychain查询,如果该项不存在,则添加该项,然后我尝试使用测试字符串更新kSecValueData,它返回错误代码-50,这意味着我输入的一个或多个参数有错误使用secItemUpdate错误代码-50在iOS中更新kSecValueData,ios,keychain,Ios,Keychain,我在这里不知所措,我创建了一个keychain查询,如果该项不存在,则添加该项,然后我尝试使用测试字符串更新kSecValueData,它返回错误代码-50,这意味着我输入的一个或多个参数有错误 NSString *initial = @""; NSData *initData = [initial dataUsingEncoding:NSUTF8StringEncoding]; //Create Search Dictionary For Phone Number... NSDictiona
NSString *initial = @"";
NSData *initData = [initial dataUsingEncoding:NSUTF8StringEncoding];
//Create Search Dictionary For Phone Number...
NSDictionary *secPhoneItem = @{ (__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecReturnData : (__bridge id)kCFBooleanTrue,
(__bridge id)kSecValueData : initData
};
//Check to see if keychain already exists by using secItemCopyMatching and associated status code
OSStatus PhoneCheckStatus = SecItemCopyMatching((__bridge CFDictionaryRef)secPhoneItem, NULL);
//Check Status Code Phone
if (PhoneCheckStatus == errSecItemNotFound) //If Phone Keychain Item Does Not already Exist
{
//Add Phone Number To Keychain
SecItemAdd((__bridge CFDictionaryRef)secPhoneItem, NULL);
}
//Update Phone Number to String
NSString *string = @"Test String";
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *attributesForUpdate = @{
(__bridge id)kSecValueData : data
};
OSStatus news = SecItemUpdate((__bridge CFDictionaryRef)secPhoneItem, (__bridge CFDictionaryRef)attributesForUpdate);
NSLog(@"Update Status Code: %ld", news);
如果有人知道为什么或者可以透露一些信息,我现在从Apple文档中得到的唯一线索是,您只能将真实属性传递到secItemUpdate(),而不能传递“meta”属性 因此,在重新阅读文档后,我发现键值对
(\uu桥id)kSecReturnData:(\uu桥id)kCFBooleanTrue
不能用于secItemUpdate()”查询参数。为了解决我的问题并帮助更好地优化搜索,我将键值对
(uu bridge id)kSecAttrDescription:someUniqueData`与类项规范一起添加到搜索查询中,然后使我的属性字典返回状态0:SUCCESS 密钥和证书属性更新-----------
对于正常的SecItemUpdate代码,给出了两个错误:-25300(未找到项),-50(尝试在一个更新方法中更新多个项)
以下是更新方法的代码:
//搜索词典
NSMutableDictionary *searchDict = [[NSMutableDictionary alloc] init];
NSData *privateKeyTag = [NSData dataWithBytes:[keyIdentifier UTF8String] length:keyIdentifier.length];
[searchDict setObject:privateKeyTag forKey:(__bridge id)kSecAttrApplicationTag];
[searchDict setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[searchDict setObject:(__bridge id)(kSecAttrKeyTypeRSA) forKey:(__bridge id<NSCopying>)(kSecAttrKeyType)];
[searchDict setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
[searchDict setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id<NSCopying>)(kSecReturnData)];
status = SecItemCopyMatching((__bridge CFDictionaryRef)searchDict, (CFTypeRef*)&item);
if (status != errSecSuccess)
{//your code for error handling }
//dictionary for the attribute that are going to update in key of certificate
//if youwant to update your passward the add the passward attribute
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,kSecAttrAccessible, nil];
/*removing the some of the from the searching dictionary*/
[searchDict removeObjectForKey:(__bridge id)kSecReturnData];
[searchDict removeObjectForKey:(__bridge id)kSecMatchLimit];
//Creating the Array for every item in the keychain that is cert of key as Search Dictionary
NSArray *secItemclasses= @[(__bridge id)kSecClassKey,(__bridge id)kSecClassCertificate];
for (id secitemclass in secItemclasses) {
//updating the key as well as certificate attribute....//
status = SecItemUpdate((__bridge CFDictionaryRef)searchDict,(__bridge CFDictionaryRef)dict);
}
if(status != errSecSuccess)
NSMutableDictionary*searchDict=[[NSMutableDictionary alloc]init];
NSData*privateKeyTag=[NSData dataWithBytes:[keyIdentifier UTF8String]长度:keyIdentifier.length];
[searchDict setObject:privateKeyTag forKey:(u桥id)kSecAttrApplicationTag];
[searchDict setObject:(uu桥id)kSecClassKey forKey:(uu桥id)kSecClass];
[searchDict setObject:(uu桥id)(kSecAttrKeyTypeRSA)forKey:(u桥id)(kSecAttrKeyType)];
[searchDict setObject:(u桥id)kSecMatchLimitOne-forKey:(u桥id)kSecMatchLimit];
[searchDict setObject:(u桥id)kCFBooleanTrue forKey:(u桥id)(kSecReturnData)];
状态=SecItemCopyMatching((uu桥CFDictionaryRef)searchDict,(CFTypeRef*)和item);
如果(状态!=errSecSuccess)
{//您的错误处理代码}
//将在证书密钥中更新的属性的字典
//如果要更新passward属性,请添加passward属性
NSDictionary*dict=[NSDictionary Dictionary With Objects and Keys:ksecattraccessibleaftfirst仅解锁此设备后,kSecAttrAccessible,nil];
/*从搜索词典中删除某些*/
[searchDict removeObjectForKey:(_桥id)kSecReturnData];
[searchDict removeObjectForKey:(_桥id)kSecMatchLimit];
//为作为搜索字典的密钥证书的密钥链中的每个项创建数组
NSArray*secItemclasses=@[(u桥id)kSecClassKey,(u桥id)kSecClassCertificate];
for(id为secitemclass中的secitemclass){
//正在更新密钥和证书属性//
状态=SecItemUpdate((uu桥CFDictionaryRef)searchDict,(uu桥CFDictionaryRef)dict);
}
如果(状态!=errSecSuccess)
如果将kSecValueData
行从secPhoneItem
定义中去掉,会发生什么情况?我仍然得到-50@Isaact按照我阅读文档的方式,您可能只能使用查询
参数(第一个CFDictionaryRef
参数)列表中的键。。。。我认为做出这样的改变应该不会太棘手,但最终,我建议使用一个更像可可的库来处理钥匙链的东西,除非你需要底层的东西——我个人使用的比任何其他这样的库都多。