最近几天我一直在使用Cocoa,我想知道如何列出我创建的钥匙链的所有名称/帐户对?Mac附带的小钥匙链访问应用程序就能做到这一点,所以我猜这肯定是可能的?我要找的是SecItemCopyMatching吗?但是,我如何指定要搜索的密钥链呢?在这种情况下,什么是服务名称?
...am I是唯一一个认为Cocoa中的Keychain API绝对可怕的人?在过去的几个小时左右,我一直在上下地阅读文档,但我仍然一无所获:-/
发布于 2011-12-28 18:15:04
您可以使用SecItemCopyMatching遍历密钥串中的项,并使用SecKeychainFindInternetPassword或SecKeychainFindGenericPassword访问密码。
在密钥链上迭代
// iterates over keychain and pass every item found by the query to PrintAccount.
static void IterateOverKeychain() {
// create query
CFMutableDictionaryRef query = CFDictionaryCreateMutable(kCFAllocatorDefault, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(query, kSecReturnAttributes, kCFBooleanTrue);
CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitAll);
CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
// get search results
CFArrayRef result = nil;
OSStatus status = SecItemCopyMatching(query, (CFTypeRef*)&result);
assert(status == 0);
// do something with the result
CFRange range = CFRangeMake(0, CFArrayGetCount(result));
CFArrayApplyFunction(result, range, PrintAccount, nil);
}
// prints the password for a item from the keychain.
static void PrintAccount(const void *value, void *context) {
CFDictionaryRef dict = value;
CFStringRef acct = CFDictionaryGetValue(dict, kSecAttrAccount);
NSLog(@"%@", acct);
}打印密码
static void PrintPassword() {
const char *acct = "foo.bar@googlemail.com";
UInt32 acctLen = (UInt32)strlen(acct);
const char *srvr = "calendar.google.com";
UInt32 srvrLen = (UInt32)strlen(srvr);
UInt32 pwLen = 0;
void *pw = 0;
SecKeychainFindInternetPassword(nil, srvrLen, srvr, 0, nil, acctLen, acct, 0, nil, 0, kSecProtocolTypeAny, kSecAuthenticationTypeAny, &pwLen, &pw, nil);
CFStringRef pwString = CFStringCreateWithBytes(kCFAllocatorDefault, pw, pwLen, kCFStringEncodingUTF8, NO);
NSLog(@"%s %@", acct, pwString);
}发布于 2011-12-28 17:20:58
好吧,我设法枚举了密钥链条目,但是密码字段是空的。我想如果需要授权,程序会像往常一样自动要求提供密钥链密码吗?
NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys:
(id)kSecClassInternetPassword, kSecClass,
(id)kCFBooleanTrue, kSecReturnData,
(id)kCFBooleanTrue, kSecReturnAttributes,
kSecMatchLimitAll, kSecMatchLimit,
nil];
NSArray *itemDicts = nil;
OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&itemDicts);
if (status)
[MessageBox Show:(NSString*)SecCopyErrorMessageString(status, NULL)];
NSMutableArray *arr = [[NSMutableArray alloc] init];
for (NSDictionary *itemDict in itemDicts) {
NSData *data = [itemDict objectForKey:(id)kSecValueData];
NSString *pwd = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
NSString *acc = [itemDict objectForKey:(id)kSecAttrAccount];
NSString *name = [itemDict objectForKey:(id)kSecAttrLabel];
if(acc != nil) {
NSArray *values = [NSArray arrayWithObjects: (id)name, (id)acc, (id)pwd, nil];
[arr addObject:(id)values];
}
}
[itemDicts release];
NSInteger c = arr.count;
NSString *cnt = [NSString stringWithFormat:@"%d", c];
[MessageBox Show: [arr objectAtIndex:10]];https://stackoverflow.com/questions/8645652
复制相似问题