首先,我观看了 WWDC 2013 关于使用钥匙串保护秘密的会议。我想做一个基本的密码存储。看完了整个视频,但在视频的前 10 分钟找到了我需要的东西。这看起来很简单,但我不完全理解数据编码和检索是如何工作的。
问题:在 secItemCopyMatching 之后,我检查 NSData 对象以确保它在将其转换为 NSString 之前不为零。问题是,它总是为零。下面是我如何保存钥匙串条目或更新,然后是如何检索它。任何帮助和解释将非常感激。
更新(编辑):
果味极客,感谢您的回复。我已经使用 __bridge 更新了下面的代码。我的问题现在归结为,我是否正确存储和检索密码?我是两处都错了,还是只错了其中之一?我的 NSData 实例始终为零。我正在检查返回代码,并且我的 SecItemAdd 和 SecItemUpdate(当钥匙串条目存在时)工作正常。我似乎无法检索存储的数据(密码)的字符串值以将其与用户输入的密码进行比较。感谢帮助的男孩和女孩。这是我现在正在做的事情:
更新#2:(用 Fruity Geek 的答案和最终工作版本进行编辑。我的编辑仅包括对下面代码的更改。)
设置钥匙串条目:
NSData *secret = [_backupPassword dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *query = @{
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService: twServiceName,
(__bridge id)kSecAttrAccount: twAccountName,
(__bridge id)kSecValueData: secret,
};
OSStatus status =
SecItemAdd((__bridge CFDictionaryRef)query, NULL);
if (status == errSecDuplicateItem) {
// this item exists in the keychain already, update it
query = @{
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService: twServiceName,
(__bridge id)kSecAttrAccount: twAccountName,
};
NSDictionary *changes = @{
(__bridge id)kSecValueData: secret,
};
status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)changes);
}
从钥匙串中检索密码:
NSDictionary *query = @{
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService: twServiceName,
(__bridge id)kSecAttrAccount: twAccountName,
(__bridge id)kSecReturnData: @YES,
};
NSData *data = NULL;
CFTypeRef dataTypeRef = (__bridge CFTypeRef)data;
OSStatus status =
SecItemCopyMatching((__bridge CFDictionaryRef)query, &dataTypeRef);
NSData *data = (__bridge NSData *)dataTypeRef;
NSString *passcode = @"none";
if (status == errSecSuccess) {
// we found a keychain entry, set the passcode
if (data)
passcode = [NSString stringWithUTF8String:[data bytes]];
}
twServiceName 和 twAccountName 是静态 NSString。
正如我所说,我不太清楚我正在使用 __bridge 或 CFTypeRef 做什么。我浏览了苹果文档、这里的大量帖子和其他网站,但钥匙串和这些术语对我来说是全新的,我仍在试图弄清楚。希望这里有人能指出我的错误并帮助我理解。先谢谢您的帮助。
iOS 7 / Xcode 5