37

我有这段代码从给定用户名 NSString 的钥匙串中取回密码:

NSError *error = nil;
NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
NSString *pw = [SFHFKeychainUtils getPasswordForUsername:username andServiceName:appName error:&error];
if(error != nil)
    // log the error    

大多数情况下,对于大多数用户来说,这一切都很好——但对于某些特定用户来说,这个调用似乎失败(并继续失败),它返回以下错误:

The operation couldn’t be completed. (SFHFKeychainUtilsErrorDomain error -25308.)

这显然是 errSecInteractionNotAllowed - 从我读过的内容来看,我认为这意味着要访问钥匙串需要某种用户交互。

有谁知道为什么这个调用可能只对某些特定用户失败?此钥匙串条目特定于我的应用程序 - 那么为什么需要任何用户交互才能访问它?

任何指针都非常感谢...

4

2 回答 2

53

好的,所以我终于解决了这个问题。

最终,我发现有问题的用户在他们的手机上设置了锁码。如果手机被锁定,钥匙串系统将返回此 -25308 错误。

如果您只需要在应用程序在前台处于活动状态时访问钥匙串,您将永远不会看到此问题 - 但如果您需要在手机锁定或应用程序处于后台时进行处理,那么您会看到它。

在其他地方,我读到 kechain 系统的默认访问属性是 kSecAttrAccessibleAlways - 但我认为这已经过时了。似乎钥匙串系统的默认访问属性是这样的,当手机被密码锁定时,项目不可用。

解决此问题的方法是更改​​ SFHFKeychainUtils 代码以在其管理的钥匙串项上设置特定的 kSecAttrAccessible 属性(原始代码没有这样做 - 可能是因为它早于这些属性)。

这个 SFHFKeychainUtils 代码的 wordpress更新版本中包含修复程序 - 搜索 kSecAttrAccessible 以查看他们在何处添加了可访问属性代码。

希望这可以帮助其他遇到此问题的人...

于 2012-03-16T10:22:36.200 回答
2

我在 iOS 14 中遇到了这个问题,小部件扩展正在访问钥匙串以获取 JWT 令牌来调用一些休息。

显然,当设备被锁定并且我试图使用的钥匙串项目无法访问时,小部件默认也会尝试更新。

将此属性设置为 keychain 元素(swift 5 代码)后,一切似乎都在工作:

keychainItem[kSecAttrAccessible as String] = kSecAttrAccessibleAfterFirstUnlock
于 2021-06-11T07:02:33.803 回答