OSStatus错误代码-34018

时间:2015-04-20 06:47:02

标签: ios objective-c ios9 keychain

我正在使用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;
    }
}

4 个答案:

答案 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

所以-34018errSecMissingEntitlement,评论说

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)

在堆栈溢出中尝试了许多修复后,事情仍然无效。

在Xcode中切换Keychain共享功能是有用的。建立并运行,它立即工作。

enter image description here