首页 文章

确定Touch ID保护的钥匙串项是否存在?

提问于
浏览
14

有没有办法确定是否已使用Touch ID访问控制 without 提示用户使用Touch ID在iOS钥匙串中设置了项目(密码,令牌等)?在执行操作之前,我们需要确定凭证是否已保存到钥匙串(带有Touch ID保护),但我们不希望使用Touch ID提示中断用户 .

我试过以下......

NSMutableDictionary *query = ...
query[(__bridge id)kSecUseNoAuthenticationUI] = (__bridge id)kCFBooleanTrue;

OSStatus opStatus = SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL);

...

但是,当调用此代码时,用户仍会看到Touch ID提示 . 我们不希望在UI上显示 ANYTHING ,只是想要在 OSStatus 中返回错误,如果需要Touch ID的话 .

有什么想法吗?

2 回答

  • 8
    NSDictionary *query = @{
                            (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
                            (__bridge id)kSecAttrService: @"SampleService",
                            (__bridge id)kSecUseNoAuthenticationUI: @YES
                            };
    
    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        CFTypeRef dataTypeRef = NULL;
        OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)(query), &dataTypeRef);
        if (status == errSecInteractionNotAllowed) {
            NSLog(@"ITEM EXIST");
        } else if (status == errSecItemNotFound) {
            NSLog(@"ITEM DOES NOT EXIST");
        } else {
            NSLog(@"status: %@", @(status));
        }
    });
    
  • 9

    基于neoneye的代码和Swift 3.我添加了errSecAuthFailed .

    query[kSecClass as String] : kSecClassGenericPassword,
        query[kSecAttrService as String] : "serviceName"    
        query[kSecUseAuthenticationUI as String] = kSecUseAuthenticationUIFail
    
        DispatchQueue.global().async {
    
            var result : AnyObject?
            let status = SecItemCopyMatching(query as CFDictionary, &result)
    
            if status == errSecInteractionNotAllowed {
    
                DispatchQueue.main.async {
    
                    // item exists
                }
            } else if status == errSecAuthFailed {
    
                DispatchQueue.main.async {
    
                    // item exists but someone removed the touch id or passcode
                }
            } else if status == errSecItemNotFound {
    
                DispatchQueue.main.async {
    
                    // it does not exist
                }
            } else {
    
                DispatchQueue.main.async {
    
                    // another OSStatus
                }
            }
        }
    

相关问题