无法从钥匙串中拔出密码 - iOS

时间:2015-03-07 08:55:50

标签: ios keychain

我有以下方法,我使用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);

这是输出,因为您可以看到密码为null:

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;
}

1 个答案:

答案 0 :(得分:0)

轻松修复,我不得不将以下密钥添加到搜索字典中。现在它正确返回密码。

[searchDict setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];