在 Apple 提供的 KeychainItemWrapper 类出现很多问题之后,我可以让它工作,但后来我对我的代码做了一些事情,看起来现在它处于不稳定状态。
实际上我有原始的 KeychainItemWrapper 类,我只是更改了以下几行来检查结果:
OSStatus cpy = SecItemCopyMatching((CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&attributes);
NSLog(@"cpy result=%d", cpy);
if (cpy == noErr)
{
....
}
else
{
// No previous item found; add the new one.
result = SecItemAdd((CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData], NULL);
if(result == errSecDuplicateItem) {
result = SecItemDelete((CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData]);
NSLog(@"result=%d", result);
}
NSAssert( result == noErr, @"Couldn't add the Keychain Item." );
}
第一个 cpy 变量返回 -25300(找不到该项目)
SecItemAdd 返回 errSecDuplicateItem(–25299 该项目已存在)
如果函数说存在某个项目,然后我尝试删除该项目,并且 SecItemDelete 再次返回 -25300,所以......现在我无法理解发生了什么。
我用装有 iOS 6.1.3 的 iPad 运行这个测试,对此有什么想法吗?有没有办法完全重置钥匙串(keychain)并从头开始?
谢谢你的帮助
最佳答案
我在此链接中提供的信息之后发现了问题:
What makes a keychain item unique (in iOS)?
“对于 kSecClassGenericPassword 类的钥匙串(keychain)项,主键是 kSecAttrAccount 和 kSecAttrService 的组合。”
看起来 Apple 提供的 KeychainItemWrapper 示例类使用了错误的组合键,或者对我试图做的事情没有用。
无论如何,我删除了那个类,现在我使用了一些简化的方法,我把代码放在这里,可能对其他人有帮助:
- (NSString*) getKeyChainItem:(NSString*)key {
NSString* keyChainValue = NULL;
NSData *attributes = NULL;
NSMutableDictionary* keyChainParams = [self createKeyChainDict:key];
[keyChainParams setObject:key forKey:(id)kSecAttrService];
[keyChainParams setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
if (SecItemCopyMatching((CFDictionaryRef)keyChainParams, (CFTypeRef *)&attributes) == noErr)
{
keyChainValue = [[[NSString alloc] initWithBytes:[attributes bytes] length:[attributes length]
encoding:NSUTF8StringEncoding] autorelease];
}
return keyChainValue;
}
- (BOOL) setKeyChainItem:(NSString*)key withValue:(NSString*)value {
NSMutableDictionary* keyChainParams = [self createKeyChainDict:key];
[keyChainParams setObject:[value dataUsingEncoding:NSUTF8StringEncoding] forKey:(id)kSecValueData];
return SecItemAdd((CFDictionaryRef)keyChainParams, NULL) == noErr;
}
- (NSMutableDictionary*)createKeyChainDict:(NSString*)key {
NSMutableDictionary* keyChainParams = [[NSMutableDictionary alloc] init];
[keyChainParams setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
[keyChainParams setObject:@"" forKey:(id)kSecAttrLabel];
[keyChainParams setObject:@"" forKey:(id)kSecAttrDescription];
[keyChainParams setObject:key forKey:(id)kSecAttrService];
[keyChainParams setObject:key forKey:(id)kSecAttrAccount];
return keyChainParams;
}
如何使用它:
NSString* myValue = [self getKeyChainItem:@"myStoredVvalue"];
[self setKeyChainItem:@"myStoredVvalue" withValue:@"12345"];
关于ios - KeychainItemWrapper 奇怪的行为,相同项目的现有/不存在项目错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24835625/