访问Keychain中的安全项有时会在iOS中返回错误-25308(errSecInteractionNotAllowed)

时间:2015-10-19 16:02:24

标签: ios security error-handling keychain

我发现有时候在尝试使用Keychain API获取以前成功存储的安全项目时会出现错误。当我在我的设备中运行的应用程序处于后台状态并锁定屏幕时,我找到了它。设备没有锁定代码集,这就是我正在调用的功能:

+ (NSString *)findValueForKey:(NSString *)keyStr
{
   NSString *valueStr = @"";

   if ((keyStr != nil) && (![keyStr isEqualToString:@""])) {
       NSString *service = [[NSBundle mainBundle] bundleIdentifier];

       NSDictionary *query = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
                            (__bridge id)kSecAttrService : service,
                            (__bridge id)kSecAttrAccount : keyStr,
                            (__bridge id)kSecReturnData : (__bridge id)kCFBooleanTrue};

       CFDataRef cfValue = NULL;
       OSStatus results = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&cfValue);

       if ([self checkIfNoError:results]) {
           valueStr = [[NSString alloc] initWithData:(__bridge_transfer NSData *)cfValue encoding:NSUTF8StringEncoding];
       }

       else {
          NSLog(@"%@", [self getErrorMessageForStatus:results]);
       }
   }

   return valueStr;
}

并通过调用此方法存储该项:

+ (BOOL)storeInKeychainWithKey:(NSString *)keyStr withValueStr:(NSString *)valueStr
{
   if ((keyStr != nil) && (![keyStr isEqualToString:@""]) &&
       (valueStr != nil) && (![valueStr isEqualToString:@""])) {

       NSData *valueData = [valueStr dataUsingEncoding:NSUTF8StringEncoding];
       NSString *service = [[NSBundle mainBundle] bundleIdentifier];

       NSDictionary *secItem = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
                              (__bridge id)kSecAttrService : service,
                              (__bridge id)kSecAttrAccount : keyStr,
                              (__bridge id)kSecValueData : valueData};

       CFTypeRef result = NULL;

       OSStatus status = SecItemAdd((__bridge CFDictionaryRef)secItem, &result);

       NSLog(@"%@", [self getErrorMessageForStatus:status]);

      return [self checkIfItem:status];
   }
   else {
      return NO;
   }
}

我认为钥匙串项目总是可以在iOS中访问...这post似乎是类似的东西,但我不确定它是否已被弃用,我应该如何解决这个问题...

提前致谢

1 个答案:

答案 0 :(得分:0)

我们有同样的问题,@ AppsDev,你提到的帖子是准确的。我们通过将钥匙串作为我们需要的东西的最后手段来解决它,即使我们卸载/重新安装应用程序。

我们现在循环回应用默认设置(在Swift 3中为UserDefaults.standard),以便在安装生命周期未到达“已卸载”阶段时保持该信息的便利。

如果卸载,下次安装时我们会转到钥匙串(根据定义,刚安装的应用程序不在后台,因此不会失败)。检索到数据后,我们会刷新应用程序默认值,然后我们只使用应用程序默认值。