使用secItemUpdate错误代码-50在iOS中更新kSecValueData

使用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

我在这里不知所措,我创建了一个keychain查询,如果该项不存在,则添加该项,然后我尝试使用测试字符串更新kSecValueData,它返回错误代码-50,这意味着我输入的一个或多个参数有错误

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
参数)列表中的键。。。。我认为做出这样的改变应该不会太棘手,但最终,我建议使用一个更像可可的库来处理钥匙链的东西,除非你需要底层的东西——我个人使用的比任何其他这样的库都多。