如何枚举 OS X 应用程序中的所有钥匙串项目?

neo*_*neo 2 security macos objective-c keychain core-foundation

请帮助我解决在 OS X 中枚举钥匙串项的问题。我阅读了有关在我的 iOS 应用程序中枚举所有钥匙串项的主题,但想了解如何编写相同的代码,该代码在主题中使用 Core Foundation 函数编写???我尝试这样做:

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

status = SecItemCopyMatching(query, result );
if (status != errSecSuccess)
{
    GetLastError(status);
}
Run Code Online (Sandbox Code Playgroud)

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

Mic*_*ann 5

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

如果您从正在查看的答案中获取代码并将其放入您的项目中:

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);
}
Run Code Online (Sandbox Code Playgroud)

你会得到更幸福的结果。

编辑以添加 CoreFoundation 等效项

您没有理由不能将 Cocoa 框架包含在您的 MacOS 命令行工具中(我假设您正在编写该工具)。命令行工具无法轻松包含 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);
Run Code Online (Sandbox Code Playgroud)

当我将其放入我自己的测试应用程序时,我看到大量各种钥匙串项目和证书的转储。