以编程方式检查是否设置了密码锁

时间:2011-05-31 18:03:29

标签: ios security ipad locking

由于我的应用程序将处理用户的敏感数据,我想知道是否有一种方法可以从我的应用程序检查iOS中是否设置了密码锁。

我需要检查这个的原因是因为如果用户在应用程序中有一些信息然后将其保留在桌面上并且出去几分钟。默认情况下,iPad / iPhone进入待机模式。如果设置了密码锁,则只有输入正确的密码后,任何人都可以使用ipad。这将提供额外的安全措施,以防止任何路人从应用程序中查看敏感数据。

基本上,我希望我的应用程序检查密码锁是否已设置,如果没有提示用户执行此操作。

这可能吗?

4 个答案:

答案 0 :(得分:10)

使用iOS 8,现在有一种方法可以检查用户是否设置了密码。 此代码将在iOS 7上崩溃。

目标-C:

-(BOOL) deviceHasPasscode {
    NSData* secret = [@"Device has passcode set?" dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary *attributes = @{ (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrService: @"LocalDeviceServices",  (__bridge id)kSecAttrAccount: @"NoAccount", (__bridge id)kSecValueData: secret, (__bridge id)kSecAttrAccessible: (__bridge id)kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly };

    OSStatus status = SecItemAdd((__bridge CFDictionaryRef)attributes, NULL);
    if (status == errSecSuccess) { // item added okay, passcode has been set            
        SecItemDelete((__bridge CFDictionaryRef)attributes);

        return true;
    }

    return false;
}

夫特:

func deviceHasPasscode() -> Bool {
    let secret = "Device has passcode set?".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
    let attributes = [kSecClass as String:kSecClassGenericPassword, kSecAttrService as String:"LocalDeviceServices", kSecAttrAccount as String:"NoAccount", kSecValueData as String:secret!, kSecAttrAccessible as String:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly]

    let status = SecItemAdd(attributes, nil)
    if status == 0 {
        SecItemDelete(attributes)
        return true
    }

    return false
}

答案 1 :(得分:6)

iOS 9以来,LocalAuthentication框架中有一个标记LAPolicyDeviceOwnerAuthentication

+ (BOOL)isPasscodeEnabled
{
    NSError *error = nil;
    LAContext *context = [[LAContext alloc] init];

    BOOL passcodeEnabled = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&error];

    if(passcodeEnabled) {
        NSLog(@"Passcode enabled.");
        return YES;
    }

    NSLog(@"Passcode NOT enabled: %@", error.localizedDescription);
    return NO;
}

iOS 8以来,还有另一个标志用于检查TouchID是否已启用:

+ (BOOL)isTouchIdEnabled
{
    NSError *error = nil;
    LAContext *context = [[LAContext alloc] init];

    BOOL touchIDEnabled = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error];

    if(touchIDEnabled) {
        NSLog(@"TouchID enabled.");
        return YES;
    }

    NSLog(@"TouchID NOT enabled: %@", error.localizedDescription);
    return NO;
}

答案 2 :(得分:3)

查看The Application Runtime Environment上的文件保护部分。文件保护要求用户启用密码锁定设置和有效的密码设置。如果您的应用程序写入/创建和文件,请使用NSDataWritingFileProtectionComplete选项。如果您的应用程序不使用任何文件,则创建一个虚拟文件并启用保护。

答案 3 :(得分:2)

适用于iOS 8的Xamarin.iOS解决方案...注意我在每次检查时都会调用SecKeyChain.Remove(secRecord)。我发现如果我没有包含这个,我可以让设备进入一个奇怪的状态,在每次调用SecKeyChain.Add(secRecord)

时它都试图与用户进行身份验证
private bool DetectIfPasscodeIsSet ()
{
    var secRecord = new SecRecord (SecKind.GenericPassword) {
        Label = "Check if passcode is set",
        Description = "Check if passcode is set",
        Account = "Check if passcode is set",
        Service = "Check if passcode is set",
        Comment = "Check if passcode is set",
        ValueData = NSData.FromString ("Check if passcode is set"),
        Generic = NSData.FromString ("Check if passcode is set")
    };
    SecKeyChain.Remove (secRecord); 
    secRecord.AccessControl = new SecAccessControl (SecAccessible.WhenPasscodeSetThisDeviceOnly);
    var status = SecKeyChain.Add (secRecord);
    if (SecStatusCode.Success == status) {
        SecKeyChain.Remove (secRecord);
        return true;
    }
    return false;
}