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

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

Ответ 1

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

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

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

Защита API:

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

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

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

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

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

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

Ответ 4

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

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