【问题标题】:How can I enumerate all Keychain items in my OS X application?如何枚举我的 OS X 应用程序中的所有钥匙串项目?
【发布时间】:2015-03-26 12:12:33
【问题描述】:

请帮我解决在 OS X 中枚举钥匙串项目的问题。我阅读了关于 enumerating all keychain items in my iOS application 的主题,但想了解,如何编写相同的代码,这些代码在主题中使用 Core Foundation 函数编写???我试图这样做:

CFDictionaryRef query = CFDictionaryCreate ( kCFAllocatorDefault, NULL, NULL, 0, NULL, NULL);
CFTypeRef *result = NULL;

status = SecItemCopyMatching(query, result );
if (status != errSecSuccess)
{
    GetLastError(status);
}

但是这段代码不起作用!你能帮我理解,我错在哪里。函数“SecItemCopyMatching”返回错误:传递给函数的一个或多个参数无效。错误代码:-50。

【问题讨论】:

    标签: objective-c macos security keychain core-foundation


    【解决方案1】:

    您提供的是空字典而不是有效查询。

    如果您将code from the answer you were looking at 放入您的项目中:

    NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                  (__bridge id)kCFBooleanTrue, (__bridge id)kSecReturnAttributes,
                                  (__bridge id)kSecMatchLimitAll, (__bridge id)kSecMatchLimit,
                                  nil];
    
    NSArray *secItemClasses = [NSArray arrayWithObjects:
                               (__bridge id)kSecClassGenericPassword,
                               (__bridge id)kSecClassInternetPassword,
                               (__bridge id)kSecClassCertificate,
                               (__bridge id)kSecClassKey,
                               (__bridge id)kSecClassIdentity,
                               nil];
    
    for (id secItemClass in secItemClasses) {
        [query setObject:secItemClass forKey:(__bridge id)kSecClass];
    
        CFTypeRef result = NULL;
        SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
        NSLog(@"%@", (__bridge id)result);
        if (result != NULL) CFRelease(result);
    }
    

    你会得到一个更快乐的结果。

    已编辑以添加等效的 CoreFoundation

    您没有理由不能在您的 MacOS 命令行工具中包含 Cocoa 框架(我假设您正在编写该工具)。命令行工具不能轻易包含的是 AppKit UI 框架。

    无论如何,这里是 CoreFoundation 等价物:

    CFMutableDictionaryRef query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                       &kCFTypeDictionaryKeyCallBacks,
                                       &kCFTypeDictionaryValueCallBacks);
    
    
    CFDictionarySetValue(query, kSecReturnAttributes, kCFBooleanTrue);
    CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll);
    
    CFTypeRef types[5];
    
    types[0] = kSecClassGenericPassword;
    types[1] = kSecClassInternetPassword;
    types[2] = kSecClassCertificate;
    types[3] = kSecClassKey;
    types[4] = kSecClassIdentity;
    
    CFArrayRef secItemClasses = CFArrayCreate(NULL, (void *)types, 5, &kCFTypeArrayCallBacks);
    CFIndex i, c = CFArrayGetCount(secItemClasses);
    
    for(i = 0; i<c; i++)
    {
        CFTypeRef secItemClass = CFArrayGetValueAtIndex(secItemClasses,i);
        CFDictionarySetValue(query, kSecClass, secItemClass);
    
        CFTypeRef result = NULL;
        SecItemCopyMatching(query, &result);
        NSLog(@"%@", (__bridge id)result);
        if (result != NULL) CFRelease(result);
    }
    
    CFRelease(secItemClasses);
    CFRelease(query);
    

    当我把它放到我自己的测试应用程序中时,我看到大量的各种钥匙串项目和证书。

    【讨论】:

    • 感谢您的回答。但是如果我想在没有 Cocoa.framework 的情况下编写应用程序,我应该使用 CoreFoundation.framework 来调整这段代码。根据它,我回答,我该如何修改该代码?然后,如何找到我的密码并从网站登录?
    【解决方案2】:

    OP 没有询问另一个钥匙串,但希望这会对未来的读者有所帮助。

    Michael 的代码是一种显示钥匙串中存储的“某些”项目的简单方法。我通过反复试验发现他的代码不会返回 iCloud 钥匙串。要查看 iCloud 钥匙串,请添加键/值对:

    NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                  (__bridge id)kCFBooleanTrue, (__bridge id)kSecReturnAttributes,
                                  (__bridge id)kSecMatchLimitAll, (__bridge id)kSecMatchLimit,
                                  //  added to find keychain items saved in iCloud
                                  (__bridge id)kCFBooleanTrue, (__bridge id)kSecAttrSynchronizable,
                                  nil];
    

    SecItemCopyMatching() 的查询字典很重要,但很少有人理解!

    ** 警告:这是在 iPhone 设备上测试的,而不是在 Mac 上。

    【讨论】:

      猜你喜欢
      • 2012-06-13
      • 2014-08-12
      • 1970-01-01
      • 2013-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多