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

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

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

所以基本上,我想我的应用程序检查是否设置密码锁,如果不提示用户这样做。

这可能吗?

查看“应用程序运行时环境”中的“文件保护”部分。 文件保护要求用户启用密码locking设置并设置有效的密码。 如果你的应用程序写/创build和文件,使用NSDataWritingFileProtectionComplete选项。 如果您的应用程序不使用任何文件,则创build一个虚拟文件并启用保护。

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

Objective-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 } 

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

Xamarin.iOS解决scheme为iOS 8 …注意我每次检查调用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; }