【问题标题】:SecItemCopyMatching for Touch ID without passcode fallback没有密码回退的 Touch ID 的 SecItemCopyMatching
【发布时间】:2015-03-22 09:26:31
【问题描述】:

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

但是,如果 Touch ID 解锁失败(或用户选择“输入密码”),我想展示我自己的 PIN 输入 UI。

我不希望用户在任何时候看到系统密码输入 UI。

LAContextevaluatePolicy 方法提供了这一点,但不提供任何实际的钥匙串安全性,仅提供本地身份验证。

因此我不会使用LAContext 来实现这一点。 SecItemCopyMatching 可以做到这一点吗?

【问题讨论】:

  • 投了赞成票,因为这是一个有趣的问题,可以帮助您回报您的赏金。 (是的,我也想知道这个答案,我不想显示“白屏”对话框,或者如果我必须,至少能够知道它将被显示,这样我就可以更改文本对于那个屏幕。)

标签: ios security keychain


【解决方案1】:

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

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

该选项将消失,或者:

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

自定义选项文本。虽然我知道这并不完全是 OP 所要求的,但它肯定是相关的,并且可以“退回”到想要的头脑中。

【讨论】:

    【解决方案2】:

    在 iOS 8.3 及更高版本上,密码回退选项最初是隐藏的,但如果出现的第一根手指未被识别,它仍然会出现。

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

    【讨论】:

    • 已更新以将此标记为正确的解决方案。在询问时,iOS 9 尚未发布。太好了,现在这是一个选项。
    • 那么,从 iOS 9 开始,使用钥匙串 (Security.framework) 可以为您提供与 LocalAuthentication.framework 相同的选项,还有更多
    【解决方案3】:

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

    我只是添加这个答案,因为这个问题是专门询问的:

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

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

    为了完整起见,我想提一下,如果您的应用需要向某个外部实体进行身份验证,因此您必须将凭据存储在某个地方,那么 Key-Chain 选项是比本地身份验证要考虑的选项。

    如果有人知道设备密码(可能是弱四位数等),则担心他们能够通过 Key-Chain 的后备进行身份验证是一个有争议的问题,因为 没有什么可以阻止用户添加他们的密码如果他们拥有密码,则将自己的指纹分配给设备,然后通过 Key-Chain 或本地身份验证进行身份验证,而无需选择回退

    因此,如果您因为觉得回退机制更安全而使用基于 Key-Chain 的本地身份验证,那么您可能会忽略这个小细节,从而放弃将凭据存储在安全飞地中的机会。

    我们即将为金融应用实施 TouchID,并选择 Key-Chain。其目的是让我们的用户在他们尝试为我们的应用启用 TouchID 时了解对强设备密码的需求。

    我希望这可以帮助您做出决定。

    【讨论】:

    • 感谢您指出指纹不比4位密码好,如果您知道这个技巧
    【解决方案4】:

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

    所以,让我试着解释一下我们是如何实现它的。 Apple 预计会为 Appstore 购买和 1Password 应用程序做类似的事情。

    背景:

    两种集成 Touch ID 的机制:

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

      问题:

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

      不允许使用其他后备机制,Apple 也不允许自定义后备用户界面

    2. 使用 Touch ID 直接对应用进行身份验证(称为本地身份验证)

      问题:

      未授予将机密存储到 Secure Enclave 或从 Secure Enclave 检索机密的权限

      与钥匙串访问案例相反,Apple 不允许设备密码验证作为备份 每个应用程序都需要提供自己的回退,以使用自定义 UI 处理失败的 Touch ID 案例

    关注:

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

    我们很想使用这种方法,但当我们意识到无法通过 Touch ID 进行身份验证时,唯一的后备方案就是设备密码,这让我们大吃一惊。 iOS 用户通常会配置一个四位数的密码,这比用户自定义密码的安全性要低。

    整容示例:

    如果用户未能通过 Touch ID 进行身份验证,Apple 会使用您的 iCloud 帐户密码 [自定义回退机制] 作为 iTunes 商店购买的回退机制。

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


    结论

    在我们的应用中,我们通过 LocalAuthentication 使用 Touch ID 进行身份验证,我们使用我们的“应用特定 PIN 解锁功能”或客户端密码作为后备机制。

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

    示例代码:

    [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;
                             }
    ];
    

    【讨论】:

    • 我奖励这条评论。虽然我无法实现我想要的行为令人失望,但能够确认这一事实是件好事。
    • @bllakjakk- 你说你不在设备上存储密码。那么,用户使用指纹认证后如何点击认证网络服务呢?
    【解决方案5】:

    无法在 Keychain TouchID 集成中使用密码禁用回退机制。改用 LocalAuthentication(但 LocalAuthentication 只是提供了一个 TouchID 身份验证 UI,虽然与 Keychain 无关)。

    【讨论】:

      【解决方案6】:

      您可以尝试通过执行以下操作隐藏Enter Password 按钮:

      1) 定义全局函数

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

      2) 在您的application:didFinishLaunchingWithOptions: 中,通过调用将LAContext 类的isFallbackButtonVisible 方法替换为您的新实现

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

      【讨论】:

      • 这会隐藏微小的“输入密码”对话框吗?如果这就是您想要做的所有事情,还有一种更简单的方法,只需将 LAContext 的本地化FallbackTitle 设置为空字符串。 (不是零顺便说一句) -- context.localizedFallbackTitle = @""; -- 我认为 jnic 试图不显示要求您输入设备密码的全屏对话框,这发生在几次“坏手指”Touch ID 尝试之后。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-29
      • 1970-01-01
      • 1970-01-01
      • 2021-07-29
      • 1970-01-01
      相关资源
      最近更新 更多