在iOS应用中,是否可以同时使用Touch-ID身份验证和Keychain共享?

17

我已经成功实现了使用钥匙串的TouchID和Keychain Sharing(在多个设备之间同步钥匙串项目)。但是当我尝试同时使用它们时,会出现错误“-50”,即无效参数。

从下面的代码中可以看出,删除kSecAttrAccessControlkSecAttrSynchronizable中的任意一个都可以正常工作。

根据我的经验(阅读 - 几天的挫折)以及一些钥匙串API简化工具(例如UICKeychainStore)的功能,如果我使用Touch ID身份验证,则Keychain Sharing将无法工作,反之亦然。我正在寻找苹果文档,说明这一点,但无法找到。

我已经查看了苹果的SecItem.h页面,并发现一个有用的信息如下所述:kSecAttrAccessiblekSecAttrSynchronizable: “如果在OS X或iOS上指定了这两个属性,则kSecAttrAccessible键的值只能是不以“ThisDeviceOnly”结尾的名称之一,因为这些不能与另一个设备同步。”但是,我没有使用“ThisDeviceOnly”(我目前正在使用kSecAttrAccessibleAlways进行测试)。

你能帮忙指出苹果是否记录了这个限制的地方吗?那将有助于我将其记录下来并继续前进。谢谢。

- (void)addKeychainItemWithIdentifier:(NSString *)identifier andData:(NSData *)data {

    CFErrorRef error = NULL;
    SecAccessControlRef sacObject;
    sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
                                            kSecAttrAccessibleAlways,
                                            kSecAccessControlUserPresence, &error);
    if(sacObject == NULL || error != NULL)
    {
    NSString *msg0 = [NSString stringWithFormat:NSLocalizedString(@"SEC_ITEM_ADD_CAN_CREATE_OBJECT", nil), error];
    [self printResultWithMessage:msg0];
    return;
    }

    NSDictionary *attributes = @{
                             (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
                             (__bridge id)kSecValueData: data,
                             (__bridge id)kSecAttrAccessible:(__bridge id)kSecAttrAccessibleAlways,
                             (__bridge id)kSecAttrService: identifier,
                             (__bridge id)kSecAttrSynchronizable:(__bridge id)kCFBooleanTrue,
                             (__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacObject
                             };

    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    OSStatus status =  SecItemAdd((__bridge CFDictionaryRef)attributes, nil);
    NSError *statuserror = [NSError errorWithDomain:NSOSStatusErrorDomain code:status userInfo:nil];
    [self printResultWithMessage:[self keychainErrorToString:status]];
    });
}
2个回答

3
我认为我可能已经找到了这个问题的答案。在WWDC 2014视频711中,31:48提到了以下内容:“ACL受保护项目-无同步,无备份”。因此,Touch ID身份验证不能用于设备之间的钥匙串共享,因为这些项目仅限于设备。

1

是的,那就是我提到的实现Touch ID身份验证的项目。但它并不包括设备之间的钥匙串共享。 - SuPotter
我可能错了,但据我所知,TouchID在设备内部有自己的存储空间,无法通过任何方式读取并共享数据给操作系统。我只是从观看WWDC发布TouchID的演示中得知这一点。 - LunaCodeGirl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接