我需要在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 :(得分:0)
我已按照以下步骤将自己的密钥和值存储到Keychain,
它很棒!
1.创建一个NSObject类
2.Import
#import<Security/Security.h>
框架
3.在头文件中添加,
- (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.在实施文件中添加,
- (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 mark - Keychain Delegates
- (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 @"";
}