ios - KeychainItemWrapper 奇怪的行为,相同项目的现有/不存在项目错误

标签 ios keychain ios6.1

在 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/

相关文章:

ios - Xcode 6 swift multiple segues with prepare for segue

ios - 删除 iOS 应用程序时删除私有(private)(钥匙串(keychain))数据

iphone - 如何找到 View 中包含的 subview 对象的种类?

ios - 向UILabel添加额外的空间以插入图像

ios - WKWebView Inside View 和 Inside ScrollView 失去联系 iOS 9

objective-c - SecCertificateAddToKeychain - 导入中的格式未知

ios - 从 KeychainItem 中检索值

ios - 尝试实例化 AVAudioPlayer 时,NSBundle 找到 mp3 文件但找不到 m4a

iphone - iOS 模拟器在虚拟机中崩溃

ios - ScrollView 中的弹出窗口