我正在使用以下代码:
+ (void)createKeychainItem:(NSString *)name
{
// Don't create if one already exists
if ([self getKeychainItem:name] != nil) return;
NSData *encodedName = [name dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *attributes = @{
(id)kSecAttrAccount : encodedName,
(id)kSecAttrGeneric : encodedName,
(id)kSecAttrLabel : name,
(id)kSecAttrService : name,
(id)kSecClass : (id)kSecClassGenericPassword,
};
OSStatus result = SecItemAdd((CFDictionaryRef)attributes, NULL);
}
+ (NSDictionary *)getKeychainItem:(NSString *)name
{
// Build the query
NSData *encodedName = [name dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *query = @{
(id)kSecAttrAccount : encodedName,
(id)kSecAttrGeneric : encodedName,
(id)kSecAttrService : name,
(id)kSecClass : (id)kSecClassGenericPassword,
(id)kSecMatchLimit : (id)kSecMatchLimitOne,
(id)kSecReturnAttributes : (id)kCFBooleanTrue,
};
NSDictionary *output = nil;
OSStatus result = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&output);
// Convert the password if it exists
NSData *passwordData = [output objectForKey:kSecValueData];
if (passwordData != nil) {
NSMutableDictionary *mutableOutput = [[output mutableCopy] autorelease];
NSString *password = [[[NSString alloc] initWithBytes:passwordData length:passwordData.length encoding:NSUTF8StringEncoding] autorelease];
[mutableOutput setObject:password forKey:(id)kSecValueData];
output = [[mutableOutput copy] autorelease];
}
return output;
}
+ (void)updateKeychainItem:(NSString *)name value:(NSString *)value attribute:(id)attribute
{
// Get the item
NSDictionary *values = [self getKeychainItem:name];
// If we got nothing back, build it
if (values == nil) {
[self createKeychainItem:name];
}
// Create a query to update
NSData *encodedName = [name dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *query = @{
(id)kSecAttrAccount : encodedName,
(id)kSecAttrGeneric : encodedName,
(id)kSecAttrService : name,
(id)kSecClass : (id)kSecClassGenericPassword,
};
NSDictionary *attributes = nil;
if (attribute == kSecValueData) {
attributes = @{ (id)kSecValueData : [value dataUsingEncoding:NSUTF8StringEncoding] };
} else {
attributes = @{ attribute : value };
}
OSStatus result = SecItemUpdate((CFDictionaryRef)query, (CFDictionaryRef)attributes);
}
使用作品设置值,[self updateKeychainItem:AuthTokenIdentifer value:authToken attribute:kSecValueData];
我可以在钥匙串访问中看到它。
使用作品获取结果NSDictionary *values = [self getKeychainItem:AuthTokenIdentifer];
,但未在字典中设置 kSecValueData。其他所有内容都已设置,例如创建和修改日期,而不是安全数据。
有任何想法吗?这发生在 iOS 和 Mac 上。