最近的堆栈溢出有用的光明之光,
在 SecItemAdd()的钥匙串条目中使用 kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly 属性时,还需要包含哪些其他属性?我的理解是 kSecAttrAccessControl 和 kSecUseAuthenticationUI 是合适的,因此使用SecAccessControlRef实例和@(BOOL)。然而,这对我不起作用。
我试图在两个钥匙串条目中保存两个词典。
一个是成功的,另一个是失败的, 成功的那个使用 kSecAttrAccessibleAfterFirstUnlock 来获取可访问性。 失败的那个使用 kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly ,并且失败的状态为errSecParam(-50) - 表明我在传递给SecItemAdd()时使用的参数不正确。
在成功的钥匙串条目中,字典中有5个键/值对传递给SecItemAdd()。
keychainQuery __NSDictionaryM * 5 key/value pairs
[0] @"svce" : @"session"
[1] @"acct" : @"com.xxx.yyy”
[2] @"v_Data" : 490 bytes
[3] @"class" : @"genp"
[4] @"pdmn" : @"ck"
@“pdmn”的@“ck”值对应于kSecAttrAccessibleAfterFirstUnlock辅助功能属性。 钥匙串项目已添加,并且可以检索并成功从中读取数据。
在不成功的钥匙串条目中,字典中有7个键/值对传递给SecItemAdd()。
keychainQuery __NSDictionaryM * 7 key/value pairs
[0] @"svce" : @"credentials"
[1] @"acct" : @"com.xxx.yyy”
[2] @"v_Data" : 370 bytes
[3] @"class" : @"genp"
[4] @"pdmn" : @"akpu"
[5] @"accc" : (no summary)
[6] @"u_AuthUI" : @"1"
@“pdmn”的@“akpu”值对应于kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly可访问性属性。 对于这个字典,还使用SecAccessControlRef实例和@(YES)指定了kSecAttrAccessControl和kSecUseAuthenticationUI。
以下是基本查询的创建方式:
+ (NSMutableDictionary *)getKeychainQuery
{
NSMutableDictionary *queryDict = [NSMutableDictionary dictionary];
queryDict[(__bridge id)kSecClass] = (__bridge id)kSecClassGenericPassword;
queryDict[(__bridge id)kSecAttrService] = [self service];
queryDict[(__bridge id)kSecAttrAccount] = [self account];
if( [self userPresence] )
{
CFErrorRef error = NULL;
SecAccessControlRef sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
[self accessibility],
kSecAccessControlUserPresence, &error);
if (error == NULL || sacObject != NULL)
{
queryDict[(__bridge id)kSecAttrAccessControl] = (__bridge_transfer id)sacObject;
queryDict[(__bridge id)kSecUseAuthenticationUI] = @YES;
}
}
return queryDict;
}
以下是用法:
+ (void)saveToKeychain:(XGKeychainItem *)keychainItem
{
NSMutableDictionary *keychainQuery = [self getKeychainQuery];
keychainQuery[(__bridge id)kSecAttrAccessible] = (__bridge id)[self accessibility];
NSData *keychainData = [NSKeyedArchiver archivedDataWithRootObject:keychainItem];
keychainQuery[(__bridge id)kSecValueData] = keychainData;
OSStatus addStatus = SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL);
NSLog(@"ADD STATUS: %d for service - %@", (int)addStatus, [self service]);
}
如果在将问题字典传递给SecItemAdd()之前,我删除了第一个字典中没有的两个属性,并将可访问性设置为与第一个字符匹配,则成功添加了keychain项。
所以,似乎我使用kSecUseAuthenticationUI,kSecAttrAccessControl和/或我的SecAccessControlRef有问题。但是,所有这些似乎都可以查看文档和我能找到的所有示例代码,以及我挖出的所有Stack Overflow线程。
我搞砸了什么?为什么其中一个参数不适合iOS?如果删除了可疑违规属性,我可以毫无问题地解码数据,因此我确信我的密码数据字典不是问题。我的伤害是什么?
答案 0 :(得分:0)
我花了更多时间在example code from Apple上,并仔细查看了与SecItemAdd()一起使用的钥匙串查询字典。
我的问题是包含了不必要的属性键。的 kSecAttrAccessible 强>
这弄乱了作品。
以下是传递给SecItemAdd()的字典中包含的适当键列表:
kSecClassGenericPassword
kSecAttrService
kSecAttrAccount (optional)
kSecValueData
kSecUseNoAuthenticationUI
kSecAttrAccessControl
kSecUseAuthenticationContext
我希望这可以节省一些人的头脑。