我正在使用SecItemCopyMatching
来访问iOS钥匙串。大约一百次,我在从后台重新启动应用程序后立即获得-34018
结果代码。 The documentation州:
Keychain Services的指定错误空间是不连续的: -25240到-25279和-25290到-25329。钥匙扣项目 服务也可以返回noErr(0)或paramErr(-50)或CSSM结果 码
因此-34018
似乎是一个' CSSM结果代码'。我已按照suggested link但无法找到结果代码。
-34018
结果代码是什么?如何获得更可靠的钥匙串访问?
- (NSData *)getKeychainData:(NSString *)key
{
NSDictionary *query = @{
(__bridge id)kSecClass:(__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService:SEC_ATTR_SERVICE,
(__bridge id)kSecAttrAccount:key,
(__bridge id)kSecReturnData:@YES
};
CFDataRef result = nil;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
if(status == errSecItemNotFound) {
return nil;
}
if(status == noErr) {
return CFBridgingRelease(result);
} else {
[self logError:[NSString stringWithFormat:@"SecItemCopyMatching status %d", (int)status] :nil];
return nil;
}
}
答案 0 :(得分:21)
我一直在研究同样的错误。
它的要点是苹果安全服务用于与密钥链进行通信,在极少数情况下,当用户的设备内存不足,崩溃并带走应用程序与之交谈的能力时钥匙串导致可怕的-34018。
只有在某些人声称可以声称的Xcode中运行时才会发生这种情况。
这是有关问题taken from the Apple developer forums by one of the Apple staff:
的最新数据更新:我们终于能够在iOS上重现-34018错误 8.3。这是确定根本原因然后提出修复的第一步。
像往常一样,我们无法承诺发布时间表,但事实并非如此 影响了许多开发人员,我们真的希望得到解决。
早些时候我建议添加一个小延迟 application:didFinishLaunchingWithOptions和 applicationDidBecomeActive:在访问钥匙串之前 解决方法。但是,这似乎并没有帮助。这意味着 除了重新启动之外,目前还没有已知的解决方法 应用程序。
这个问题似乎与记忆压力有关,所以可能存在 更积极地处理内存警告可以缓解这个问题。
来自另一位Apple员工:
- 钥匙串工程很清楚这个问题的重要性。
- 主要问题是在Apple重现失败。
- 我们现在能够做到这一点(很大程度上要归功于你们在提交和跟踪你的错误报告时所做的工作)。
来自另一位Apple员工 2016年3月22日:
好的,这是最新的。这是一个复杂的问题 可能的原因:问题的某些情况是由不正确引起的 应用签名。您可以轻松区分这种情况,因为问题 100%可重复。问题的一些实例是由a引起的 iOS如何支持应用程序开发的错误(r.23,991,853)。调试 操作系统中的另一个错误(r。 23,770,418)掩盖了它的效果,意味着问题只会出现 当设备处于内存压力下时。我们相信这些问题 已在iOS 9.3中解决。我们怀疑可能还有更多原因 这个问题。因此,如果您在用户设备上看到此问题(一个 那个运行iOS 9.3或更高版本的Xcode尚未与之交谈的, 请提交有关它的错误报告。尝试包含该设备 系统登录你的错误报告(我意识到这可能是棘手的 处理客户设备;一种选择是询问客户 安装Apple Configurator,让他们查看系统日志)。和 如果您确实提交了错误,请发布您的错误号,仅供参考 记录。代表Apple,我要感谢大家 努力帮助追查这个相当可怕的问题。分享和 享受
很遗憾没有已知的解决方法,但在9.3.2 Beta 1(13F51a)
中仍未解决此问题答案 1 :(得分:20)
经过一番研究,我发现了这一点:http://opensource.apple.com/source/Security/Security-55471/sec/Security/SecBasePriv.h
所以-34018
是errSecMissingEntitlement
,评论说
Internal error when a required entitlement isn't present.
运行单元测试时是否遇到此错误?如果是这样,这可能会有所帮助:https://stackoverflow.com/a/22305193/171933
github上的这个问题说,只有从Xcode调试时才会发生这种情况:https://github.com/soffes/sskeychain/issues/97(另见https://stackoverflow.com/a/28256591/171933)
希望其中一些有用!
答案 2 :(得分:4)
此代码适用于我:
static const UInt8 kKeychainItemIdentifier[] = "com.apple.dts.KeychainUI\0";
- (NSData *)getKeychainData:(NSString *)key
{
NSData *keychainItemID = [NSData dataWithBytes:kKeychainItemIdentifier length:strlen((const char *)kKeychainItemIdentifier)];
NSDictionary *query = @{
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService: SEC_ATTR_SERVICE,
(__bridge id)kSecAttrAccount: key,
(__bridge id)kSecReturnData: (__bridge id)kCFBooleanTrue,
(__bridge id)kSecAttrGeneric: keychainItemID
};
CFDataRef result = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
if(status == errSecItemNotFound) {
return nil;
}
if(status == noErr) {
return CFBridgingRelease(result);
} else {
[self logError:[NSString stringWithFormat:@"SecItemCopyMatching status %d", (int)status] :nil];
return nil;
}
}
与OP代码的主要区别在于为查询添加了通用属性。 Keychain Item Identifier是apple的默认值。这背后的原因是区分可能的不同钥匙串项目。这是使钥匙串项目访问更加可靠的一种方法。基本上,换句话说,这可以确保您访问Apple的默认钥匙串。
答案 3 :(得分:0)