iOS KeyChain不从后台检索值

Bil*_*ess 81 iphone background keychain lockscreen ios

我目前正在iOS KeyChain中存储用户名(电子邮件)和电子邮件和密码的盐渍哈希.我正在使用这里发现的ARC'ified版本.

KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"MyCustomIdentifier" accessGroup:nil];
[wrapper setObject:APP_NAME forKey:(__bridge id)kSecAttrService];
[wrapper setObject:email forKey:(__bridge id)kSecAttrAccount];
[wrapper setObject:token forKey:(__bridge id)kSecValueData];
Run Code Online (Sandbox Code Playgroud)

当我需要在应用程序处于活动状态时拉出令牌以进行网络呼叫时,这一切都正常.它适用于从干净的启动登录,以及整个网络调用.当应用程序在后台时,问题就开始了.

请记住,这只是零星发生,我还没有把它固定到特定的iOS版本或设备上.

用户绊倒一个位置(区域监控),我想用他们的状态更新服务器.我尝试将令牌从钥匙串中取出,就像我为每个其他网络呼叫所做的那样,并更新状态.但对于一些用户来说,价值是零.没有它,我无法更新网络内容.为什么这对大多数人有效,但对于一小部分人来说不是这样?

KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"MyCustomIdentifier" accessGroup:nil];
NSString *token = [wrapper objectForKey:(__bridge id)kSecValueData];
Run Code Online (Sandbox Code Playgroud)

我已经回到了keychainwrapper的非ARC版本,但我仍然得到了相同的结果.我将不胜感激任何反馈.它只是我用户的一小部分,但这是一个我想解决的问题而不用担心.提前致谢.

此外,我的所有后台工作都在backgroundTask中设置,以防止事情超时.我对钥匙链的工作没有任何问题,但在令牌填满之前我不会让事情继续下去.

编辑 我发现我的问题是他们的钥匙串没有从后台检索值.我将在下面发布答案并接受它,因为我觉得这个问题可能会在以后对其他人有价值.

Bil*_*ess 105

我的问题接近原因,但原因并不完全.经过博客后阅读博客,教程后的教程,我终于找到了一个可以发生可能发生的事情.

锁定主屏幕.钥匙串教程始终将钥匙串的辅助功能设置留空,因此默认为Apple最低/最安全的访问级别.但是,如果用户在锁定屏幕上有密码,则此级别不允许钥匙串访问.答对了!这解释了零星的行为以及为什么这只发生在一小部分用户身上.

一行代码解决了整个问题.

[wrapper setObject:(__bridge id)kSecAttrAccessibleAlways forKey:(__bridge id)kSecAttrAccessible];
Run Code Online (Sandbox Code Playgroud)

在我设置用户名和密码值的位置添加此行.奇迹般有效.希望这会帮助那里的人.直到我能把这些碎片放在一起,这让我困惑了很长一段时间.

  • 这是一个非常糟糕的主意,因为这意味着此凭据数据不再受到保护.虽然做了一些工作,但创建一个*衍生凭证*比仅用于您希望在后台需要的有限访问权限而不是更多.有限的凭证可以在一段时间后过期,每次打开应用程序时都会创建一个新凭证,使旧的凭证无效.这可以在衍生凭证受到损害时保证用户安全.请参阅WWDC 2013会话204以了解相关信息. (14认同)
  • 如果可能的话,请避免使用"... AccessibleAlways",或者存储仅提供有限权限的令牌(例如,允许您阅读新订阅源但不发布的令牌).您通过这样做明确地放弃了加密级别.如果您的应用程序可以等到第一次解锁,那么最好使用`... AfterFirstUnlock`并指导您的用户首先解锁他们的设备. (13认同)
  • 在这里回应@JoeyHagedorn - 听听WWDC 2013会议204"多任务有什么新功能",时间为44:24,WWDC 2013会议709"用钥匙扣保护秘密",时间为25:30.您可以在http://asciiwwdc.com上查看这些会谈的文本内容 (7认同)
  • 几个星期以来,我们一直在处理这个问题.你是一个救生员! (3认同)

woo*_*oof 57

kSecAttrAccessibleAfterFirstUnlock而不是kSecAttrAccessibleAlways.


来自Apple的文档:

kSecAttrAccessibleAfterFirstUnlock
重启后,无法访问钥匙串项中的数据,直到用户解锁设备一次.

第一次解锁后,数据保持可访问状态,直到下次重新启动.建议用于需要后台应用程序访问的项目.使用加密备份时,具有此属性的项目将迁移到新设备.

  • 这个答案应该是评论...... (4认同)