没有密码回退的Touch ID的SecItemCopyMatching

我正在使用SecItemCopyMatching来获取由Touch ID保护的钥匙串项目。

但是,如果Touch ID解锁失败(或者用户select“input密码”),我想呈现我自己的PINinputUI。

我不希望用户在任何时候出现系统密码inputUI。

LAContextevaluatePolicy方法提供了这个,但是不提供任何实际的钥匙串安全性,仅仅是本地authentication。

因此,我不会使用LAContext来实现这一点。 这可能与SecItemCopyMatching

在iOS 8.3及以上版本中,密码后备选项最初是隐藏的,但如果第一个手指未被识别,仍会出现。

对于iOS 9,添加了两个不会回退到密码的新策略。 这些策略是kSecAccessControlTouchIDAny和kSecAccessControlTouchIDCurrentSet

这应该是对bllakjakk的一个评论,但是我的名声不允许我这样做。

我只是添加这个答案,因为这个问题是具体问:

获取受Touch ID保护的钥匙串项目

接受的答案提到了设备上没有存储凭据的场景。

为了完整起见,我想提到的是,如果您的应用程序需要对某个外部实体进行身份validation,并且您因此必须在某处存储凭据,那么通过本地身份validation就需要考虑Key-Chain选项。

如果他们知道设备密码(可能弱四位数等等),那么担心有人能够通过Key-Chain的后备进行身份validation,因为没有任何东西可以阻止用户将自己的指纹添加到设备中他们拥有密码,然后通过密钥链或本地身份validation进行身份validation,而无需select回退

因此,如果您使用本地身份validation而不是密钥链,因为您认为回退机制更安全,那么您可能会忽视这些细节,因此会放弃在安全区域中存储凭据的机会。

我们即将实施TouchID金融应用程序,并select钥匙链。 目的是教育我们的用户在他们尝试为我们的应用程序启用TouchID时需要强壮的设备密码。

我希望这可以帮助你作出决定。

在开发我们的一个在线应用程序时,我们遇到了类似的困境。 我们意识到我们需要触摸ID解锁以及比4位解锁密码更强的自定义回退机制(需要服务器API进行解锁)。

所以,让我试着解释我们如何实现它。 预计苹果将为Appstore购买和1Password应用程序做类似的工作。

背景:

两个整合Touch ID的机制:

  1. 使用Touch ID访问存储在钥匙串中的凭证

    问题:

    如果设备也有Touch ID,首选方法是使用Touch ID进行validation,密码是备份机制

    没有其他回退机制是允许的,苹果不允许自定义回退用户界面

  2. 使用Touch ID直接进行身份validation(称为本地身份validation)

    问题:

    将秘密存储到安全区域或从安全区域检索秘密是不允许的

    与钥匙串访问情况相反,苹果不允许将设备密码authentication作为备份每个应用程序都需要提供自己的后备处理,以处理失败的触摸ID与自定义用户界面

关心:

关于在钥匙串中存储敏感信息:

我们很想使用这种方法,但由于意识到唯一无法通过Touch ID进行身份validation的后果而感到吃惊,因为设备密码是设备密码。 iOS用户通常configuration一个四位密码,这比用户自定义密码的安全性要低。

举重例子:

如果用户无法使用Touch ID进行身份validation,Apple会将您的iCloud帐户密码[自定义回退机制]用作itunes商店购买的后备机制。

1Password应用程序也有类似的方法。


结论

在我们的应用程序中,我们通过LocalAuthentication使用Touch ID进行身份validation,我们使用“应用程序特定的PIN解锁function”或客户端的密码作为回退机制。

我们不会在设备上存储密码 ,如果设备没有在应用程序内configurationPIN,则无法通过Touch ID进行身份validation需要通过服务器API进行完全身份validation。

示例代码:

 [self.laContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:reason reply:^(BOOL success, NSError *error) { if (success) dispatch_async(dispatch_get_main_queue(), ^{ successBlock(); }); else dispatch_async(dispatch_get_main_queue(), ^{ fallbackBlock(error); }); self.laContext = nil; } ]; 

您可以尝试通过执行以下操作隐藏“ Enter Passwordbutton:

1)定义全局函数

 static bool new_isFallbackButtonVisible(id self, SEL _cmd) { return NO; } 

2)在你的application:didFinishLaunchingWithOptions:通过调用你的新实现来replaceLAContext类的isFallbackButtonVisible方法

 class_replaceMethod(NSClassFromString(@"LAContext"), NSSelectorFromString(@"isFallbackButtonVisible"), (IMP)new_isFallbackButtonVisible, "v@:B"); 

Keychain TouchID集成中无法使用密码禁用回退机制。 改用LocalAuthentication(但LocalAuthentication只提供一个TouchIDauthentication用户界面,但与钥匙串无关)。

您可以通过设置来隐藏/自定义“input密码”选项:

 LAContext *context = [[LAContext alloc] init]; context.localizedFallbackTitle = @""; 

该选项将消失,或者:

 LAContext *context = [[LAContext alloc] init]; context.localizedFallbackTitle = @"Disable TouchID"; 

自定义选项文本。 虽然我知道这不是OP所要求的,但它肯定是相关的,可以“回退”成想要的人。