2016-11-07 85 views
0

我需要在Keychain中存储多个具有唯一密钥的密码/密码。在从钥匙串中获取存储的数据时,我得到零值。任何人都可以帮我解决这个问题吗?如何使用唯一密钥在Keychain类中存储多个密码?

这是我的代码...

- (void)storeSensitiveDataToKeychain:(NSString *)value withKey:(NSString *)key { 
    NSString *keyValue = [self fetchDataFromKeychain:key]; 
    if ([keyValue isEqualToString:@""] || [keyValue isEqual:[NSNull null]] || !keyValue.length || keyValue == nil) { 
     [keychainClass insert:key :[value dataUsingEncoding:NSUTF8StringEncoding]]; 
    } else { 
     [keychainClass update:key :[value dataUsingEncoding:NSUTF8StringEncoding]]; 
    } 
} 

- (NSString *)fetchDataFromKeychain:(NSString *)key { 

    NSData *value = [keychainClass find:key]; 
    if (value == nil) { 
     NSLog(@"key value is nil"); 
     return @""; 
    } else { 
     return [[NSString alloc] initWithData:value 
                encoding:NSUTF8StringEncoding]; 
    } 
} 
+0

如果你想存储多个密码,然后使用必须是'username'或'用户的email'关键,因为这些键是唯一的,这样你可以存储它,稍后用'email'或'username'检索它。 – Rajat

+0

谢谢Rajat,我将密钥用作电子邮件。如果可能,你可以分享任何样本吗? – Surezz

+0

您正在使用哪个类来存储钥匙串,如SSKeychain或其他? – Rajat

回答

0

我按照下面的步骤来存储我自己的键和值到钥匙扣,

它工作真棒!

1.创建一个NSObject类

2.Import

#import<Security/Security.h>框架

3.In头文件添加,

- (id) initWithService:(NSString *) service_ withGroup:(NSString*)group_; 

- (BOOL)insert:(NSString *)key dataValue:(NSData *)data; 
- (BOOL)update:(NSString*)key dataValue:(NSData*)data; 
- (BOOL)remove:(NSString*)key; 
- (NSData*)find:(NSString*)key; 

3.In实施文件添加,

- (id) initWithService:(NSString *) service_ withGroup:(NSString*)group_ { 
    self =[super init]; 
    if(self) { 
     service = [NSString stringWithString:service_]; 
     if(group_) 
      group = [NSString stringWithFormat:@"%@.%@",[KeyChain bundleSeedID],group_]; 
    } 
    NSLog(@"%@",group); 
    return self; 
} 

- (NSMutableDictionary*)prepareDict:(NSString *)key { 

    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; 
    [dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; 

    NSData *encodedKey = [key dataUsingEncoding:NSUTF8StringEncoding]; 
    [dict setObject:encodedKey forKey:(__bridge id)kSecAttrGeneric]; 
    [dict setObject:encodedKey forKey:(__bridge id)kSecAttrAccount]; 
    [dict setObject:service forKey:(__bridge id)kSecAttrService]; 
    [dict setObject:(__bridge id)kSecAttrAccessibleAlwaysThisDeviceOnly forKey:(__bridge id)kSecAttrAccessible]; 

    //This is for sharing data across apps 
    if(group != nil) 
     [dict setObject:group forKey:(__bridge id)kSecAttrAccessGroup]; 

    return dict; 
} 

- (BOOL)insert:(NSString *)key dataValue:(NSData *)data { 

    NSMutableDictionary * dict =[self prepareDict:key]; 
    [dict setObject:data forKey:(__bridge id)kSecValueData]; 

    OSStatus status = SecItemAdd((__bridge CFDictionaryRef)dict, NULL); 
    if(errSecSuccess != status) { 
     NSLog(@"Unable add item with key =%@ error:%d",key,(int)status); 
    } 
    return (errSecSuccess == status); 
} 

- (NSData*)find:(NSString*)key { 
    NSMutableDictionary *dict = [self prepareDict:key]; 
    [dict setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; 
    [dict setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData]; 
    CFTypeRef result = NULL; 
    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)dict,&result); 

    if(status != errSecSuccess) { 
     NSLog(@"Unable to fetch item for key %@ with error:%d",key,(int)status); 
     return nil; 
    } 

    return (__bridge NSData *)result; 
} 

- (BOOL)update:(NSString*)key dataValue:(NSData*)data { 

    NSMutableDictionary * dictKey =[self prepareDict:key]; 
    NSMutableDictionary * dictUpdate =[[NSMutableDictionary alloc] init]; 
    [dictUpdate setObject:data forKey:(__bridge id)kSecValueData]; 

    OSStatus status = SecItemUpdate((__bridge CFDictionaryRef)dictKey, (__bridge CFDictionaryRef)dictUpdate); 
    if(errSecSuccess != status) { 
     NSLog(@"Unable add update with key =%@ error:%d",key,(int)status); 
    } 
    return (errSecSuccess == status); 

    return YES; 
} 

- (BOOL)remove: (NSString*)key { 
    NSMutableDictionary *dict = [self prepareDict:key]; 
    OSStatus status = SecItemDelete((__bridge CFDictionaryRef)dict); 
    if(status != errSecSuccess) { 
     NSLog(@"Unable to remove item for key %@ with error:%d",key,(int)status); 
     return NO; 
    } 
    return YES; 
} 

+ (NSString *)bundleSeedID { 
    NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys: 
          (__bridge NSString *)kSecClassGenericPassword, (__bridge NSString *)kSecClass, 
          @"bundleSeedID", kSecAttrAccount, 
          @"Service_name", kSecAttrService, 
          (id)kCFBooleanTrue, kSecReturnAttributes, 
          nil]; 
    CFDictionaryRef result = nil; 
    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result); 
    if (status == errSecItemNotFound) 
     status = SecItemAdd((__bridge CFDictionaryRef)query, (CFTypeRef *)&result); 
    if (status != errSecSuccess) 
     return nil; 
    NSString *accessGroup = [(__bridge NSDictionary *)result objectForKey:(__bridge NSString *)kSecAttrAccessGroup]; 
    NSArray *components = [accessGroup componentsSeparatedByString:@"."]; 
    NSString *bundleSeedID = [[components objectEnumerator] nextObject]; 
    CFRelease(result); 
    return bundleSeedID; 
} 

@end 

无论你需要什么,你都可以调用下面这些方法。

确保您的密钥名称可能相同。

的#pragma马克 - 钥匙扣代表

- (void)storeSensitiveDataToKeychain:(NSString *)value withKey:(NSString *)key { 
    [keychainClass insert:[key lowercaseString] :[value dataUsingEncoding:NSUTF8StringEncoding]]; 
} 

- (NSString *)fetchDataFromKeychain:(NSString *)key { 
    NSString *keyValue = [[NSString alloc] initWithData:[keychainClass find:[key lowercaseString]] encoding:NSUTF8StringEncoding]; 
    if (keyValue.length > 0 && ![keyValue isEqual:[NSNull null]]) { 
     return keyValue; 
    } 
    return @""; 
} 
相关问题