检查 iOS 设备首次解锁以确定使用 kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly 存储的项目是否可用

Checking for iOS device first unlock to determine if items stored with kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly are available

假设以下情况:

  1. 用户重新启动 his/her iPhone.
  2. 用户让设备锁定,确实 不解锁。
  3. 服务器在 设备(或任何唤醒应用程序的事情发生在 后台,比如 Apple Watch 扩展请求数据等)。
  4. 应用唤醒并尝试访问存储在 kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly 辅助功能中的钥匙串项目。

现在,应该无法访问钥匙串项,因为设备尚未解锁。如何正确检查这种情况?

注意:在我的例子中,存储在钥匙串中的项目的存在决定了应用程序是否是 "active",所以我需要一些东西来尽快停止这个检查,否则我的应用程序会假设它未激活(无法读取值)并执行初始步骤...

我在我的应用中遇到过同样的情况,下面是我检查钥匙串是否可用的方法(objective-c 代码):

+ (BOOL)isKeychainAvailable {
    NSString *testVal = @"testVal";
    NSString *testKey = @"testKey";
    [JNKeychain saveValue:testVal forKey:testKey];
    NSString *validatedValue = [JNKeychain loadValueForKey:testKey];
    [JNKeychain deleteValueForKey:testKey];
    return (validatedValue == testVal);
}

我基本上是在keychain中保存一个值,然后再尝试读取。如果它与我刚刚写的不一样,则意味着钥匙串不可用,这也意味着 phone 尚未通过第一次解锁,因为由于选项 [,钥匙串在第一次解锁后应该可用 kSecAttrAccessibleAfterFirstUnlock.

在这种情况下,如果应用程序在后台启动且钥匙串不可用,我最终会终止该应用程序:

- (void) methodStartedInBackgroundThatNeedsKeychain {
    if (!JNKeychain.isKeychainAvailable && [UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
        exit(0);
    }
}

注意! 请注意,Apple 强烈反对在应用程序处于前台模式时使用 exit(0),这就是为什么我确保只调用它在背景中 [UIApplication sharedApplication].applicationState != UIApplicationStateActive。这是 Apple 对此主题的 QA 讨论:https://developer.apple.com/library/archive/qa/qa1561/_index.html