无法从钥匙串中提取密码 - iOS
Unable to pull password from keychain - iOS
我有以下创建钥匙串项并使用 SecItemAdd()
将其添加到钥匙串的方法。当我尝试取回密码时,我无法在我的控制台中看到它。我在设备上 运行,而不是模拟器。
- (NSMutableDictionary *)createKeychainDictionaryWithIdentifier:(NSString *)identifier username:(NSString *)username password:(NSString *)password{
NSMutableDictionary *dict = [@{} mutableCopy];
[dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
NSData *identifierData = [identifier dataUsingEncoding:NSUTF8StringEncoding];
NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
[dict setObject:(__bridge id)kSecAttrAccessibleWhenUnlocked forKey:(__bridge id)kSecAttrAccessible];
[dict setObject:identifierData forKey:(__bridge id)kSecAttrGeneric];
[dict setObject:username forKey:(__bridge id)kSecAttrAccount];
[dict setObject:passwordData forKey:(__bridge id)kSecValueData];
[dict setObject:service forKey:(__bridge id)kSecAttrService];
return dict;
}
- (BOOL)addClientWithKeyChainIdentifier:(NSString *)identifier username:(NSString *)username password:(NSString *)password{
NSMutableDictionary *client = [self createKeychainDictionaryWithIdentifier:identifier username:username password:password];
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)client, NULL);
if(status != errSecSuccess)
return NO;
DLog(@"status: %i", (int)status);
//Add identifier to clients array
[_clients addObject:identifier];
return YES;
}
- (NSDictionary *)searchForItemWithIdentifier:(NSString *)identifier{
NSMutableDictionary *searchDict = [@{} mutableCopy];
NSData *identifierData = [identifier dataUsingEncoding:NSUTF8StringEncoding];
//Define search dictionary
[searchDict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
[searchDict setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
[searchDict setObject:identifierData forKey:(__bridge id)kSecAttrGeneric];
[searchDict setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes];
CFDictionaryRef dict = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)searchDict, (CFTypeRef *) &dict);
if(status != errSecSuccess)
return nil;
NSDictionary *result = (__bridge NSDictionary *)dict;
return result;
}
这是我测试上述方法的代码:
[keychainManager addClientWithKeyChainIdentifier:@"Nikita" username:@"Nikita" password:@"Volkov"]
NSDictionary *dict = [keychainManager searchForItemWithIdentifier:@"Nikita"];
NSData *data = [dict objectForKey:(__bridge id)kSecValueData];
DLog(@"Password: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
DLog(@"Dictionary: %@", dict);
这是输出,您可以看到密码为空:
Password:
Dictionary: {
acct = Nikita;
agrp = "97CYSL4U6B.com.Nikita.MyApp";
cdat = "2015-03-07 08:51:35 +0000";
gena = <4e696b69 7461>;
mdat = "2015-03-07 08:51:35 +0000";
pdmn = ak;
svce = "com.Nikita.MyApp";
sync = 0;
tomb = 0;
}
很容易修复,我必须将以下键添加到搜索字典中。现在 returns 密码正确了。
[searchDict setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
我有以下创建钥匙串项并使用 SecItemAdd()
将其添加到钥匙串的方法。当我尝试取回密码时,我无法在我的控制台中看到它。我在设备上 运行,而不是模拟器。
- (NSMutableDictionary *)createKeychainDictionaryWithIdentifier:(NSString *)identifier username:(NSString *)username password:(NSString *)password{
NSMutableDictionary *dict = [@{} mutableCopy];
[dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
NSData *identifierData = [identifier dataUsingEncoding:NSUTF8StringEncoding];
NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
[dict setObject:(__bridge id)kSecAttrAccessibleWhenUnlocked forKey:(__bridge id)kSecAttrAccessible];
[dict setObject:identifierData forKey:(__bridge id)kSecAttrGeneric];
[dict setObject:username forKey:(__bridge id)kSecAttrAccount];
[dict setObject:passwordData forKey:(__bridge id)kSecValueData];
[dict setObject:service forKey:(__bridge id)kSecAttrService];
return dict;
}
- (BOOL)addClientWithKeyChainIdentifier:(NSString *)identifier username:(NSString *)username password:(NSString *)password{
NSMutableDictionary *client = [self createKeychainDictionaryWithIdentifier:identifier username:username password:password];
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)client, NULL);
if(status != errSecSuccess)
return NO;
DLog(@"status: %i", (int)status);
//Add identifier to clients array
[_clients addObject:identifier];
return YES;
}
- (NSDictionary *)searchForItemWithIdentifier:(NSString *)identifier{
NSMutableDictionary *searchDict = [@{} mutableCopy];
NSData *identifierData = [identifier dataUsingEncoding:NSUTF8StringEncoding];
//Define search dictionary
[searchDict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
[searchDict setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
[searchDict setObject:identifierData forKey:(__bridge id)kSecAttrGeneric];
[searchDict setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes];
CFDictionaryRef dict = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)searchDict, (CFTypeRef *) &dict);
if(status != errSecSuccess)
return nil;
NSDictionary *result = (__bridge NSDictionary *)dict;
return result;
}
这是我测试上述方法的代码:
[keychainManager addClientWithKeyChainIdentifier:@"Nikita" username:@"Nikita" password:@"Volkov"]
NSDictionary *dict = [keychainManager searchForItemWithIdentifier:@"Nikita"];
NSData *data = [dict objectForKey:(__bridge id)kSecValueData];
DLog(@"Password: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
DLog(@"Dictionary: %@", dict);
这是输出,您可以看到密码为空:
Password:
Dictionary: {
acct = Nikita;
agrp = "97CYSL4U6B.com.Nikita.MyApp";
cdat = "2015-03-07 08:51:35 +0000";
gena = <4e696b69 7461>;
mdat = "2015-03-07 08:51:35 +0000";
pdmn = ak;
svce = "com.Nikita.MyApp";
sync = 0;
tomb = 0;
}
很容易修复,我必须将以下键添加到搜索字典中。现在 returns 密码正确了。
[searchDict setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];