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

9
假设以下情况: 1. 用户重新启动了他/她的iPhone。 2. 用户让设备处于锁定状态,没有解锁它。 3. 服务器在设备上发送了(静默)推送通知(或任何其他使应用程序在后台唤醒的事件,如Apple Watch扩展请求数据等)。 4. 应用程序唤醒并尝试访问使用kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly可访问性存储的Keychain项。
现在,由于设备尚未解锁,因此不应该能够访问Keychain项。如何正确检查这种情况?
注意:在我的情况下,钥匙串中存储的某个项目的存在确定应用程序是否处于“活动”状态,因此我需要停止此检查,否则我的应用程序将假定它不处于活动状态(无法读取值)并执行初始化步骤...
1个回答

5

我在我的应用中遇到了同样的情况,以下是我如何检查钥匙串是否可用(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中保存一个值,然后尝试再次读取它。如果它与我刚刚写的值不同,这意味着keychain不可用,这也意味着手机还没有经过第一次解锁,因为选项 kSecAttrAccessibleAfterFirstUnlock 应该在第一次解锁后可用。

在这种情况下,我最终做的是,如果应用程序在后台启动并且keychain不可用,则终止该应用程序:

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

注意!请注意,苹果公司强烈反对在应用程序处于前台模式时使用exit(0)函数,因此我只会在后台调用该函数,如下:[UIApplication sharedApplication].applicationState != UIApplicationStateActive。以下是苹果公司关于此问题的问答讨论:https://developer.apple.com/library/archive/qa/qa1561/_index.html


1
我会接受这个答案 - 我喜欢解决方案的要点(使用kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly标志存储值并立即尝试读取它),聪明!谢谢。 - Petr Dvořák

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接