iOS 8 (OS X Yosemite) представил новый API/константу, используемый для определения того, имеет ли пользовательское устройство код доступа.
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
может использоваться для определения того, установлен ли пароль на устройстве.
Течение:
- Попытка сохранить новый элемент на брелка с этим набор атрибутов
- Если это удается, что указывает на то, что код доступа в данный момент включен
- Если пароль не получить сохраненный, что указывает на отсутствие кода доступа
- Очистка элемента, потому что, если он уже находится на брелках, он сделает ошибку «добавить», похоже, что код доступа не установлен
Я тестировал это на своем iPhone 5S, сначала он вернул true
, затем я отключил пароль в настройках, и он вернул false
.Наконец, я снова включил код доступа, и он возвращает true
. Предыдущие версии ОС вернут false
. Код работает в симуляторе, возвращая true
на компьютере с набором пароля OS X (я не тестировал альтернативные сценарии OS X).
Также см пример проекта здесь: https://github.com/project-imas/passcode-check/pull/5
Наконец, к моему знанию IOS 8 не имеет настройки, чтобы отключить защиту данных, поэтому я предполагаю, что это все, что вам нужно, чтобы гарантировать шифрование.
BOOL isAPIAvailable = (&kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly != NULL);
// Not available prior to iOS 8 - safe to return false rather than crashing
if(isAPIAvailable) {
// From http://pastebin.com/T9YwEjnL
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
};
// Original code claimed to check if the item was already on the keychain
// but in reality you can't add duplicates so this will fail with errSecDuplicateItem
// if the item is already on the keychain (which could throw off our check if
// kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly was not set)
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)attributes, NULL);
if (status == errSecSuccess) { // item added okay, passcode has been set
NSDictionary *query = @{
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService: @"LocalDeviceServices",
(__bridge id)kSecAttrAccount: @"NoAccount"
};
status = SecItemDelete((__bridge CFDictionaryRef)query);
return true;
}
// errSecDecode seems to be the error thrown on a device with no passcode set
if (status == errSecDecode) {
return false;
}
}
return false;
P.S. Поскольку Apple указывает на видео WWDC, представляющее это (711 Keychain и аутентификация с Touch ID), они решили не делать статус кода доступа напрямую доступным через API специально для того, чтобы предотвратить попадание приложений в ситуации, когда они не должны быть (т. е. «У этого устройства есть код доступа? Хорошо, отлично, я сохраню эту личную информацию в виде обычного текста». Было бы гораздо лучше создать ключ шифрования, сохранить его под kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
и зашифровать этот файл, который будет невосстановимым если пользователь решает отключить свой код доступа).
Я бы предположил, что блокировка паролей не имеет отношения к запущенному приложению, поэтому я думаю, что это не часть SDK. Если бы это было так, вероятно, это было бы частью этого API: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIDevice_Class/Reference/UIDevice.html –
Это очень актуально для запущенного приложения, потому что без кода доступа ваши данные не защищены на устройстве. Это был бы огромный надзор со стороны Apple, если нет способа узнать, защищены ли ваши данные или нет. Это делает новое шифрование iOS 4 практически бесполезным для большинства корпоративных приложений, продаваемых через магазин приложений. – Mike
Большинство предприятий должны (должны) иметь профиль развертывания, который был бы перенаправлен на все iPhone компании, чтобы потребовать пароль. Это не проблема программы, это проблема управления. Вы действительно хотите выставить предупреждение, в котором пользователь должен включить свой пароль? Или еще лучше, откажитесь бежать, если он не включен? Пользователям обычно не нравится, когда им говорят, что делать с их устройствами. –