【问题标题】:SecItemCopyMatching keeps returning errSecItemNotFoundSecItemCopyMatching 不断返回 errSecItemNotFound
【发布时间】:2023-03-29 12:39:01
【问题描述】:

我正在尝试使用钥匙串服务来保存一个值,即使用户重新安装该应用程序,该值也会持续存在。所以我使用SecItemCopyMatching检查一个项目是否存在,它第一次返回errSecItemNotFound,并使用SecItemAdd添加一个新项目,它返回errSecSuccess,但_attrs的值是nil。此外,当第二次调用代码时,SecItemCopyMatching 仍然返回errSecItemNotFound,就好像没有调用SecItemAdd。那么这可能与什么有关?

    CFMutableDictionaryRef _attrs = nil;
    NSString* key = @"<unique key>";
    NSMutableDictionary* query = [NSMutableDictionary dictionary];
    query[(__bridge id)kSecClass] = (__bridge id)kSecClassGenericPassword;
    query[(__bridge id)kSecAttrLabel] = key;
    query[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitOne;
    query[(__bridge id)kSecReturnAttributes] = (__bridge id)kCFBooleanTrue;

    OSStatus err = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef*)&_attrs);

    if (err == errSecSuccess) {
        return YES;
    }
    NSString* str = @"<some data>";
    if (err == errSecItemNotFound) {
        query[(__bridge id)kSecValueData] = NSData_from_string(string_from_NSString(str));
        query[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAlways;
        err = SecItemAdd((__bridge CFDictionaryRef)query, (CFTypeRef*)&_attrs);
        assert(err == errSecSuccess);
    }

【问题讨论】:

    标签: ios objective-c keychain


    【解决方案1】:

    您正在重新使用query 来调用SecItemAdd,而字典中出现的此函数的kSecMatchLimit 值破坏了它。你应该在调用SecItemAdd之前删除这个键。

    还值得注意的是,[str dataUsingEncoding:NSUTF8StringEncoding] 可能是比 NSData_from_string(string_from_NSString(str)) 更好的选择,具体取决于您在做什么。

    【讨论】:

    • 它似乎有效,但我不太明白为什么。 kSecMatch 密钥是否不适用于 SecItemAdd,或者如果我使用 kSecMatchAll 会通过吗?我不记得在阅读文档时遇到过这个......
    • SecItemCopyMatching 的文档表明您可以将文档的“搜索常量”部分中的项目(例如 kSecMatchLimit)添加到查询中。 SecItemAdd 文档没有说明这一点,而且查询中出现的此类常量似乎会中断调用(或至少使其行为不像您预期​​的那样)。
    猜你喜欢
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-19
    • 1970-01-01
    • 1970-01-01
    • 2019-11-04
    相关资源
    最近更新 更多