【问题标题】:which key should I use to store the password in iOS keychain?我应该使用哪个密钥将密码存储在 iOS 钥匙串中?
【发布时间】:2013-05-31 02:23:41
【问题描述】:

Apple GenericKeychain 示例中的 KeychainItemWrapper 类使用 kSecValueData 键来存储密码。

但是参考http://developer.apple.com/library/ios/#documentation/Security/Reference/keychainservices/Reference/reference.html#//apple_ref/doc/uid/TP30000898

说 kSecValueData 是 用于 SecItemCopyMatching 或 SecItemAdd 的结果字典中,表示返回值的类型。

当我调用 SecItemAdd 来创建钥匙串项时,我应该使用哪个键?

【问题讨论】:

    标签: ios keychain


    【解决方案1】:

    您应该使用 kSecValue 数据作为存储密码的密钥(以 NSData 或 CFDataRef 格式)。

    这个主题的参考有点不清楚,kSecValueData 键作为输出键和输入键。也就是说,您在查询钥匙串项 (SecItemCopyMatching) 并指定 kSecReturnAttributes 键时使用它,因此结果作为字典返回,密码将存储在该字典的 kSecValueData 键下。当您将项目添加到钥匙串(SecItemAdd)时,您也可以使用它,在调用方法之前将密码的 NSData 或 CFDataRef 值存储在 kSecValueData 键中。

    以下是两种情况的示例:

    找回密码:

    NSMutableDictionary *queryDictionary = [[NSMutableDictionary alloc] init];
    [queryDictionary setObject: (__bridge id)kSecClassGenericPassword forKey: (__bridge id<NSCopying>)kSecClass];
    [queryDictionary setObject:service forKey:kSecAttrService];
    [queryDictionary setObject:account forKey:kSecAttrAccount];
    // The result will be a dictionary containing the password attributes...
    [queryDictionary setObject:YES forKey:(__bridge id<NSCopying>)(kSecReturnAttributes)];
    // ...one of those attributes will be a kSecValueData with the password
    [queryDictionary setObject:YES forKey:(__bridge id<NSCopying>)(kSecReturnData)];
    OSStatus sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)(queryDictionary), (CFTypeRef *)&result);
    if (sanityCheck != noErr)
    {
        NSDictionary * resultDict = (__bridge NSDictionary *)result;
        // here's the queried password value
        NSData *passwordValue = [resultDict objectForKey:(__bridge id)(kSecValueData)];
    }
    

    添加密码:

    NSString *passwordString = @"my password value";
    NSData *passwordData = [passwordString dataUsingEncoding:NSUTF8StringEncoding];
    CFDictionaryRef result = nil;
    NSMutableDictionary *addDictionary = [[NSMutableDictionary alloc] init];
    [addDictionary setObject: (__bridge id)kSecClassGenericPassword forKey: (__bridge id<NSCopying>)kSecClass];
    [addDictionary setObject:service forKey:kSecAttrService];
    [addDictionary setObject:account forKey:kSecAttrAccount];
    
    // here goes the password value
    [addDictionary setObject:passwordData forKey:(__bridge id<NSCopying>)(kSecValueData)];
    
    OSStatus sanityCheck = SecItemAdd((__bridge CFDictionaryRef)(queryDictionary), NULL)
    if (sanityCheck != noErr)
    {
       // if no error the password got successfully stored in the keychain
    }
    

    【讨论】:

    猜你喜欢
    • 2023-03-29
    • 1970-01-01
    • 2017-09-05
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-29
    • 1970-01-01
    相关资源
    最近更新 更多