2016-11-07 10 views
0

複数のパスワード/パスコードをキーチェーンに保存する必要があります。私はキーチェーンから格納されたデータをフェッチしている間に無価値を得ています。誰にでもこのことから私を助けることができますか?Keychainクラスに複数のパスワードを一意のKeyで保存する方法は?

これは私のコードです...

- (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

私はキーホルダーに自分のキーと値を格納するための手順の下に続いている、

はそれは素晴らしい作品! NSObjectのクラス

2.Import

#import<Security/Security.h>枠組み

3.Inヘッダファイルが追加

1.Create、

- (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 @""; 
} 
関連する問題