Могу ли я запретить пользователю iOS изменять дату и время?

Я хочу развернуть управляемые устройства iOS для сотрудников компании, и приложение, которое они будут использовать, будет помечать данные, которые будут записаны локально, а затем перенаправлены. Мне нужно, чтобы эти временные метки были правильными, поэтому я должен запретить пользователю настраивать время на устройстве, записывать значение, а затем сбрасывать дату и время. Дата и время будут настроены для автоматического выхода из сети, но устройство может не иметь сетевого подключения в любое время (в противном случае я бы просто прочитал сетевое время каждый раз, когда записывается значение данных). Я не видел опции в конфигураторе Apple, чтобы предотвратить изменение даты и времени, поэтому есть другой способ сделать это?

4 ответов


вы не сможете запретить пользователю изменять свои часы или просто нажимать на API напрямую, как это сделали другие комментаторы. Это две отдельные проблемы, которые можно решить, имея локальное время, которое вы контролируете на устройстве, и генерируя хэшированный ключ того, что вы отправляете на сервер.

локальное время на устройстве:

чтобы начать, сделайте вызов API при запуске приложения, которое отправляет обратно метку времени с сервера; это ваш " фактический время". Теперь сохраните это на устройстве и запустите таймер, который использует функцию uptime телефона (не mach_absolute_time() или CACurrentMediaTime() - это странно, когда ваш телефон находится в режиме ожидания) и немного математики, чтобы увеличить, что фактическое время, каждую секунду. Я написал статью о том, как я это сделал для одного из моих приложений (обязательно прочитайте последующие в качестве оригинальной статьи используется CACurrentMediaTime() но в этом есть некоторые ошибки). Вы можете периодически делать этот первоначальный вызов API (т. е. если телефон идет в почву и возвращается снова), чтобы убедиться, что все остается точным, но время всегда должно быть правильным пока вы не перезагрузите телефон (который требует вызова API, когда вы в следующий раз открываете приложение, чтобы обновить время).

защита API:

Теперь у вас есть гарантированное* точное время на вашем устройстве, но у вас все еще есть проблема в том, что кто-то может отправить неправильное время на ваш API напрямую (т. е. не с вашего устройства). К противодействуйте этому, я бы использовал некоторую форму соли / хэша с данными, которые вы отправляете, похожими на OAuth. Например, возьмите все параметры, которые вы отправляете, объедините их вместе и хэшируйте их солью, которую знаете только вы, и отправьте этот сгенерированный ключ в качестве дополнительного параметра. На вашем сервере, вы знаете, хэш и соль, так что вы можете восстановить ключ и проверить его с тем, который был отправлен; если они не совпадают, кто-то пытается играть с вашей отметкой.

*Предостережение: A опытный атаковал может hi-jack соединение так, что любые вызовы example.com/api/timestamp приходите с другой машины, которую они создали, которая возвращает время, которое они хотят, чтобы телефон получил неправильное время в качестве начальной базы. Есть способы предотвратить это (запутывание, сопряжение с другими данными, шифрование), но это становится очень открытым вопросом очень быстро, поэтому лучше всего спросить в другом месте. Сочетание вышеперечисленного плюс монитор, чтобы заметить странные времена, может быть лучшим вещь.


кажется, нет никакого способа выполнить то, о чем вы просите. Кажется, нет способа остановить пользователя от возможности изменить время. Но помимо этого, даже если вы можете помешать им изменить время, они могут позволить своей батарее устройства умереть, затем подключить ее и включить там, где у них нет сетевого соединения, и их часы будут неправильными, пока у них не будет возможности установить себя по сети. Так что даже предотвращение их от изменения времени не гарантирует точность.

то, что вы можете сделать, это потребовать подключения к сети для записи значений, чтобы вы могли проверить время на сервере. Если вы должны позволить ему работать без сетевого подключения, вы могли бы, по крайней мере, всегда регистрировать текущее время, когда приложение поднимается, и отмечать, если время когда-либо кажется назад. Вы будете знать, что что-то происходит, если метка времени внезапно раньше, чем предыдущая метка времени. Вы также можете сделать эту проверку, возможно, только тогда, когда они пытаются записать значение. Если они запишите значение, которое имеет отметку времени раньше, чем любое предыдущее записанное значение, вы можете отклонить его или зарегистрировать событие, чтобы человек мог быть допрошен об этом позже.

Это также один из тех случаев, когда, возможно, Вам просто нужно доверять пользователю не делать этого, потому что, похоже, нет идеального решения для этого.


первое, что нужно отметить, это то, что пользователь всегда сможет подделывать сообщения на ваш сервер, чтобы создавать неправильные записи.

но есть некоторые полезные вещи, которые вы можете использовать по крайней мере замечает проблемы. В большинстве случаев лучший способ обеспечить безопасность такого рода системы-сосредоточиться на обнаружении, а затем публично наказать любого, кто сделал все возможное, чтобы обойти политику. Крепкие замки бессмысленны, если нет копа, который в конце концов появится и остановить вас.

конечно, вы должны сначала предположить, что любые ошибки времени случайны. Но просто публично "замечать", что чье-то устройство, похоже," плохо себя ведет", часто достаточно, чтобы плохое поведение исчезло.

Так что вы можете сделать? Первое, что нужно отметить, это временные метки вещей, когда они появляются на сервере. Метки всегда должны двигаться вперед во времени. Таким образом, если вы уже видели записи с устройства в понедельник, вы не должны позже получать записи для в прошлое воскресенье. То же самое должно быть верно для вашего приложения. Вы можете отслеживать, когда вы завершены в NSUserDefaults (а также размещать эту информацию на сервере). Обычно не следует просыпаться в прошлом. Если вы это сделаете, пожалуйтесь на свой сервер.

часы UIApplicationSignificantTimeChangeNotification. Я считаю, что вы получите его, если время будет изменено вручную (вы получите его и в нескольких других случаях, большинство из которых доброкачественные). Следите за временем, которое движется значительно назад. Жаловаться на свой сервер.

обратите внимание mach_absolute_time(). Это время с момента загрузки устройства и не может быть изменено пользователем без джейлбрейка. Это полезно для различения между перезагрузками и другими событиями. Он находится в странной единице времени, но его можно преобразовать в человеческое время, как описано в QA1398. Если разница во времени Маха больше, чем на час больше, чем время настенных часов, что-то странно (изменения DST могут вызвать 1 час). Жаловаться на свой разлучить.

все эти вещи могут быть доброкачественными. Человеку нужно будет разобраться и принять решение.

ни одна из этих вещей не гарантирует, что ваши записи верны, если есть выделенный и опытный злоумышленник. Как я уже сказал, преданный и опытный злоумышленник может просто отправить вам поддельные сообщения. Но эти вещи, в сочетании с контролем и дисциплинарными мерами, делают опасным для инсайдеров даже экспериментировать с тем, как победить систему.


вы не можете запретить пользователю менять время.
Даже время местоположения регулируется Apple, а не реальное время GPS. Вы можете посмотреть на время ядра mach, которое является относительным временем.
Сравните это со временем последнего сетевого подключения.

но все это звучит не надежно.