如何枚举我的 OS X 应用程序中的所有钥匙串项?
How can I enumerate all Keychain items in my OS X application?
请帮我解决在 OS X 中枚举钥匙串项的问题。我阅读了有关 enumerating all keychain items in my iOS application 的主题,但想了解如何编写相同的代码,该代码在主题中写为核心基础功能???我试着这样做:
CFDictionaryRef query = CFDictionaryCreate ( kCFAllocatorDefault, NULL, NULL, 0, NULL, NULL);
CFTypeRef *result = NULL;
status = SecItemCopyMatching(query, result );
if (status != errSecSuccess)
{
GetLastError(status);
}
但是这段代码不起作用!你能帮我理解一下,我哪里错了。函数 "SecItemCopyMatching" 返回错误:传递给函数的一个或多个参数无效。 错误代码:-50。
您提供的是空字典而不是有效查询。
如果您将 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);
当我将其放入我自己的测试应用程序中时,我看到了大量各种钥匙串项和证书的转储。
OP 没有询问另一个钥匙串,但希望这对未来的读者有所帮助。
Michael 的代码是显示钥匙串中存储的 'some' 项的简单方法。通过反复试验,我发现他的代码不会 return iCloud 钥匙串。要查看 iCloud 钥匙串,请添加 key/value 对:
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.
上测试的
请帮我解决在 OS X 中枚举钥匙串项的问题。我阅读了有关 enumerating all keychain items in my iOS application 的主题,但想了解如何编写相同的代码,该代码在主题中写为核心基础功能???我试着这样做:
CFDictionaryRef query = CFDictionaryCreate ( kCFAllocatorDefault, NULL, NULL, 0, NULL, NULL);
CFTypeRef *result = NULL;
status = SecItemCopyMatching(query, result );
if (status != errSecSuccess)
{
GetLastError(status);
}
但是这段代码不起作用!你能帮我理解一下,我哪里错了。函数 "SecItemCopyMatching" 返回错误:传递给函数的一个或多个参数无效。 错误代码:-50。
您提供的是空字典而不是有效查询。
如果您将 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);
当我将其放入我自己的测试应用程序中时,我看到了大量各种钥匙串项和证书的转储。
OP 没有询问另一个钥匙串,但希望这对未来的读者有所帮助。
Michael 的代码是显示钥匙串中存储的 'some' 项的简单方法。通过反复试验,我发现他的代码不会 return iCloud 钥匙串。要查看 iCloud 钥匙串,请添加 key/value 对:
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.
上测试的