SecItemCopyMatch for Touch ID,无需密码回退



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

但是,如果触控 ID 解锁失败(或用户选择"输入密码"),我想提供自己的 PIN 输入 UI。

我不希望在任何时候向用户显示系统密码条目 UI。

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

因此,我不会使用LAContext来实现这一目标。这在SecItemCopyMatching可能吗?

在 iOS 8.3 及更高版本上,密码回退选项最初是隐藏的,但如果显示的第一根手指无法识别,则仍会显示。

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

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

所以,让我试着解释一下我们如何实现它。预计苹果也将在Appstore购买和1Password应用程序方面进行类似的操作。

背景:

集成触控 ID 的两种机制:

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

    问题:

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

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

  2. 使用触控 ID 直接向 App 进行身份验证(称为"本地身份验证")

    问题:

    未授予将机密存储到安全隔区

    或从安全隔区检索机密的权限

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

关注:

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

我们很想使用这种方法,但意识到无法使用Touch ID进行身份验证的唯一回退是设备密码,这让我们大吃一惊。 iOS 用户通常配置四位数密码,这不如用户自定义密码安全。

整容示例:

如果用户无法使用触控 ID 进行身份验证,Apple 会使用您的 iCloud 帐户密码 [自定义回退机制] 作为 iTunes Store 购买的后备机制。

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


结论

在我们的应用程序中,我们通过本地身份验证使用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的评论,但我的声誉还不允许我这样做。

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

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

接受的答案提到了设备上未存储任何凭据的情况。

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

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

因此,

如果您因为认为回退机制更安全而通过钥匙链使用本地身份验证,您可能会忽略这个小细节,因此错过了在安全隔区中存储凭据的机会。

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

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

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

1) 定义全局函数

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

2)在你的application:didFinishLaunchingWithOptions:通过调用isFallbackButtonVisible用你的新实现替换LAContext类的方法

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

无法在钥匙串 TouchID 集成中使用密码禁用回退机制。请改用 LocalAuthentication(但 LocalAuthentication 仅提供 TouchID 身份验证 UI,尽管与钥匙串无关)。

您可以通过设置以下内容隐藏/自定义"输入密码"选项:

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

并且该选项将消失,或者:

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

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

最新更新