Apple GenericKeychain 示例中的 KeychainItemWrapper 类使用 kSecValueData 键来存储密码。
表示 kSecValueData 在 SecItemCopyMatching 或 SecItemAdd 的结果字典中使用,表示返回值的类型。
当我调用 SecItemAdd 来创建钥匙串项时,我应该使用哪个键?
Apple GenericKeychain 示例中的 KeychainItemWrapper 类使用 kSecValueData 键来存储密码。
表示 kSecValueData 在 SecItemCopyMatching 或 SecItemAdd 的结果字典中使用,表示返回值的类型。
当我调用 SecItemAdd 来创建钥匙串项时,我应该使用哪个键?
您应该使用 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
}