SecItemAdd和SecItemCopyMatching返回错误代码-34018(errSecMissingEntitlement)

有时当我从Xcode运行设备上的应用程序时,我会尝试访问钥匙串,但由于错误-34018而失败。 这不符合任何logging的钥匙串错误代码,不能一致地复制。 (可能有30%的时间,而且我不清楚为什么会这样)。 什么使得debugging这个问题非常困难的是完全缺乏文档。 任何想法是什么导致这个问题,以及如何解决它? 我正在使用Xcode 5并在设备上运行iOS 7.0.4。

这里有一个公开的问题: https : //github.com/soffes/sskeychain/issues/52

编辑:每个请求添加钥匙串访问代码

我正在使用SSKeychain库来连接钥匙串。 这是片段。

 #define SERVICE @"default" @implementation SSKeychain (EXT) + (void)setValue:(NSString *)value forKey:(NSString *)key { NSError *error = nil; BOOL success = NO; if (value) { success = [self setPassword:value forService:SERVICE account:key error:&error]; } else { success = [self deletePasswordForService:SERVICE account:key error:&error]; } NSAssert(success, @"Unable to set keychain value %@ for key %@ error %@", value, key, error); if (!success) { LogError(@"Unable to set value to keychain %@", error); } LogTrace(@"Will set keychain account %@. is to nil? %d", key, value == nil); if (value == nil) LogWarn(@"Setting keychain %@ to nil!!!", key); } + (NSString *)valueForKey:(NSString *)key { NSError *error = nil; NSString *value = [self passwordForService:SERVICE account:key error:&error]; if (error && error.code != errSecItemNotFound) { NSAssert(!error, @"Unable to retrieve keychain value for key %@ error %@", key, error); LogError(@"Unable to retrieve keychain value for key %@ error %@", key, error); } return value; } + (BOOL)removeAllValues { LogInfo(@"Completely Reseting Keychain"); return [[self accountsForService:SERVICE] all:^BOOL(NSDictionary *accountInfo) { return [self deletePasswordForService:SERVICE account:accountInfo[@"acct"]]; }]; } @end 

绝大多数时间都很好。 有时候我会发现断言失败,我无法写入或读取钥匙链,从而导致严重的断言失败。

iOS 10 / XCode 8修正:

添加KeyChain权利,转到项目设置 – >function – >钥匙串共享 – >添加钥匙串组+打开

苹果回答:

更新:我们终于能够在iOS 8.3上重现-34018错误。 这是确定根本原因然后提出修复的第一步。

像往常一样,我们不能承诺发布的时间框架,但这已经影响了许多开发人员,我们真的希望得到解决。

早些时候,我build议在应用程序中添加一个小延迟:didFinishLaunchingWithOptions和applicationDidBecomeActive:在访问钥匙串之前作为一种解决方法。 但是,这实际上并没有帮助。 这意味着除了重新启动应用以外,目前还没有已知的解决方法。

这个问题似乎与记忆压力有关,所以在处理记忆警告时可能更积极一些,可能会缓解这个问题

https://forums.developer.apple.com/thread/4743#14441

UPDATE

好的,这是最新的。
这是一个复杂的问题,有多种可能的原因:

  • 某些问题的实例是由不正确的应用程序签名造成的。 您可以很容易地区分这种情况,因为问题是100%可重现的。
  • 这个问题的一些实例是由iOS如何支持应用程序开发(r。23,991,853)中的一个错误引起的。 由于OS(23,770,418)的另一个缺陷掩盖了它的效果,这意味着当设备处于内存压力下时,问题才会出现。 我们相信这些问题已经在iOS 9.3中解决了。
  • 我们怀疑这个问题可能还有更多的原因。

因此,如果您在运行iOS 9.3或更高版本的用户设备(未经Xcode讨论的设备)上看到此问题,请提交有关此问题的错误报告。 尝试将设备系统日志包含在你的bug报告中(我认识到在处理客户设备时可能会非常棘手;一种select是要求客户安装Apple Configurator,以便他们查看系统日志)。 如果你提交了一个bug,请发布你的bug号码,以备logging。

我谨代表苹果,感谢大家为帮助追踪这个相当可怕的问题所做的努力。 分享和享受

https://forums.developer.apple.com/thread/4743#126088

这个线程似乎包含解决scheme,如果问题退出你的unit testing目标。

https://devforums.apple.com/message/917498#917498

基本上,你必须通过在testing目标中添加以下内容作为运行脚本来对.xcttest文件夹进行编码。

 codesign --verify --force --sign "$CODE_SIGN_IDENTITY" "$CODESIGNING_FOLDER_PATH" 

在设备上testing我的钥匙串时,我遇到了很多-34018错误,并且设法解决了这个错误。

如果问题不存在于您的testing目标中,这可能不是解决scheme。

在使用iOS 8 SDK(Xcode 5 / iOS 7正常工作)构build和运行我的代码之后,我观察到了类似的行为。 在Xcode 6中,在iOS模拟器中,SecItemCopyMatching始终返回-34018。 在Capabilities选项卡中打开“Keychain Sharing”后,它开始工作。

不过我还有一个问题。 我正在开发静态库,这是由(等)演示应用程序使用。 上面的解决scheme适用于Demo应用程序项目,但是当我尝试unit testing我的静态库项目时,我有完全相同的错误。 问题是我的静态库项目没有能力选项卡(因为它不是独立的应用程序)。

我已经尝试了JorgeDeCorte在这里发布的解决scheme,在testing目标中进行了代码设置,但是这对我不起作用。

检查源代码后 。 我注意到钥匙串function是通过一个在自己的进程中运行的安全守护进程来访问的(与应用进程分开)。

您的应用和安全stream程通过名为XPC的技术“交谈”。

如果有必要的话,这个安全是通过XPC的着名的launchd命令启动的。 你可能可以检查守护进程是否在Activity Monitor App中运行(如果在Simulator中运行的话),并且它的父进程是启动的。

我的猜测是,有可能是因为任何未知的原因,安全守护进程无法启动或执行得太慢,并且在您尝试使用它时没有做好准备。

也许你可以考虑如何预先启动守护进程。

我很抱歉没有更精确。 我希望这可以帮助你进一步调查。

尝试从Xcode 启动应用程序时禁用所有断点 。 之后您可以启用它们。

(上述解决方法都不适用于我)

我在运行7.1和8.0的模拟器上遇到同样的问题。 在做一些挖掘工作的时候,我注意到苹果示例应用程序已经开启了KeyChain Sharingfunction。 我打开了我的应用程序,导致创build一个授权文件,我留下了默认值,现在我不再有-34018错误。 这不是理想的,但我现在将生活KeyChain分享选项。

我已经解决了这个问题(我认为)。 我的设备上有一个通配符configuration文件,显示它没有有效的签名标识。 我的应用程序configuration文件也是有效的。 当我删除通配符configuration文件时,我停止得到-34018错误。

我还确保目标的“生成设置”的“代码签名”部分中列出的代码签名身份和configurationconfiguration文件与应用程序的configuration文件(不是通用的“iPhone开发人员”configuration文件)

我也被这个咬了,也没有任何其他的解决方法成功。 然后,我通过删除所有与我的应用程序相关的configuration文件以及所有通配符configuration文件(这似乎是要点)来清理我的configuration文件。 为此,请转到Xcode的“设备”窗口,然后右键单击您的(连接的)电话:

点击“显示configuration文件”并删除相关的configuration文件,尤其是团队configuration文件:

包括带有星号的那些。 重新安装应用程序后,一切恢复正常。

在一些情况下,对一个.xctest包进行编码并不像听起来那么简单。 主要是JorgeDeCorte的答案是正确的,即作为Run Script的给定短线对于大部分的开发者来说已经足够了。

 codesign --verify --force --sign "$CODE_SIGN_IDENTITY" "$CODESIGNING_FOLDER_PATH" 

但是,如果您的钥匙串中有多个证书,则会失败,并显示以下行

 iPhone Developer: ambiguous (matches "iPhone Developer: Your Name (ABC123DEF45)" and "iPhone Developer: Your Name (123ABC456DE)" 

即使有多个正确的证书的解决scheme是这个简短的脚本。 可以肯定的是,这并不理想,但就我所知,您没有机会获得Xcodefind并用于签署.app的证书。

 echo "codesign --verify --force --sign \"$CODE_SIGN_IDENTITY\" \"$CODESIGNING_FOLDER_PATH\"" IDENTITIES=`security find-identity -v -s "Code Signing" | grep "iPhone Developer" | awk '{ print $2 }'` for SHA in $IDENTITIES; do codesign --verify --force --sign $SHA "$CODESIGNING_FOLDER_PATH" if [ $? -eq 0 ]; then echo "Matching identity found: $SHA" exit 0 fi done; exit 1 

我很less在我的应用程序(iOS 8.4)中出现-34018错误。 经过一番调查,我发现当应用程序太频繁地从钥匙串请求数据时会发生这个问题。
例如,在我的情况下,来自不同的应用程序模块的是同时对一个特定键的两个读取请求。
为了解决这个问题,我刚刚添加了caching这个值在内存中

我在使用Xcode 6.2,iPhone 6,iOS 8.3的testing设备上出现同样的问题。 要清楚的是,这在运行Xcodetesting时没有经历,而是在我的设备上运行实际的应用程序。 在模拟器很好,运行在应用程序本身,直到最近它已经完全没问题。

我尝试了所有可以在这里find的build议,例如删除设备上的configuration文件(我删除了所有这些configuration文件),临时启用项目中的“钥匙串共享”function(即使我们不需要)确定我在Xcode的开发账户完全刷新了所有的证书和configuration文件等没有什么帮助。

然后,我暂时将可访问性级别从kSecAttrAccessibleAfterFirstUnlockkSecAttrAccessibleAlwaysThisDeviceOnly ,运行该应用程序,它工作正常,并能写入钥匙串。 然后我把它改回到kSecAttrAccessibleAfterFirstUnlock ,问题似乎已经“永久”消失了。

刚刚被Xcode 8 Beta 3上的这个bug所困扰。开启Keychain Sharing似乎是唯一的解决scheme。

我遇到过同样的问题。 通过设置钥匙串共享来修复它。

(这不是OP的问题的直接答案,但可以帮助其他人)

在将Xcode从V7.3.1更新到8.0之后,开始在仿真器中始终获得钥匙串错误-34018。

根据代代的回答 ,

某些问题的实例是由不正确的应用程序签名造成的。 您可以很容易地区分这种情况,因为问题是100%可重现的。

发现Provisioning Profile在目标的签名部分中已经被设置为None。

但是,在这种情况下,将“供应configuration文件”字段设置为有效值不足以解决问题。

进一步调查显示,推送通知权利也显示错误。 它表示“将推送通知function添加到您的应用程序ID”。 步骤已完成,但步骤“将推送通知权利添加到您的权利文件”不是。

按“修复问题”修复推送通知问题后,钥匙串错误已解决。

对于这个特定的目标,“钥匙串共享”权利已经在前一段时间被打开。 closures钥匙链错误至今还没有出现,所以在这种情况下是否需要重新设置。

在iOS 9中,我closures了Address Sanitizer并开始在设备上工作。

我唯一的解决scheme是首先存储指定键的nil ,然后用一个单独的操作存储我的新值。 如果我试图覆盖现有的值,则会因为错误-34018而失败。 但只要我先存储 ,那么更新后的值将立即成功存储。

运行SecItemDelete API时,我今天遇到了这个-34018问题。 我做了什么来解决这个问题是:1.以下@ k1th解决schemehttps://stackoverflow.com/a/33085955/889892 2.在主线程中运行SecItemDelete(以前它是从主线程读取,所以只需将其与删除alignment) 。

对不起,它又回来:(

打开钥匙串共享您的项目的能力,它应该解决问题。 在这里输入图像说明