Что такое safetynet android

SafetyNet Attestation — описание и реализация проверки на PHP

В эту тему пришлось детально погрузиться во время работы над обеспечением стандартных механизмов верификации устройств для разных мобильных платформ. Задача сводилась к разработке полноценной реализацию проверки JWS-токенов по протоколу SafetyNet на серверной стороне.

После многочасовых поисков и скрупулёзного изучения официальной документации Google решил поделиться полученным опытом. Потому что, кроме официальной документации, я нашел только отрывочные описания частных примеров реализации на разных ЯП. И ни намека на комплексное объяснение особенностей проверки по SafetyNet на сервере.

Статья будет полезна разработчикам, которые хотят подробнее разобраться с технологией верификации устройств по протоколу SafetyNet Attestation. Для изучения описательной части не обязательно знать какой-либо язык программирования. Я сознательно убрал примеры кода, чтобы сфокусироваться именно на алгоритмах проверки. Сам пример реализации на PHP сформулирован в виде подключаемой через composer библиотеки и будет описан ниже.

А в конце статьи — ссылка на разработанную мной библиотеку на PHP, которая обеспечивает полный цикл верификации JWS.

Дисклеймер: материал в явном виде содержит перевод официальной документации от Google с разъяснениями и описанием особенностей реализации, с которыми я столкнулся.

О технологии

Технология SafetyNet Attestation разработана Google как средство предоставления разработчикам мобильных приложений информации о надёжности приложения клиента при взаимодействии с сервером, который обслуживает мобильное приложение. Для этого в протоколе взаимодействия предусмотрен удостоверяющий сервис от Google, обеспечивающий верификацию, и представлены рекомендации по проверке ответа от удостоверяющего центра на стороне сервера.

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

Что позволяет проверить технология:

Что именно вы являетесь автором приложения, которое сейчас взаимодействует с сервером.

Что в процессе взаимодействия клиента и сервера нет больше никого, кроме вашего приложения и сервера.

Что операционная система мобильного устройства не претерпела изменений, критичных для обеспечения безопасного обмена с сервером (не «заручено» — не взломано, а также то, что устройство прошло аттестацию совместимости с Android).

В каких случаях механизм не применим или не имеет смысла:

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

Если попытаемся выполнить верификацию подписанного токена в самом мобильном приложении (без участия сервера), так как проверка клиента не должна происходить на клиенте. Если у вас приложение без Backend, или вы в принципе не планируете верификацию SafetyNet на серверной части приложения, то нет смысла устанавливать и настраивать этот механизм проверки.

Читайте также:  Geometry dash pdalife для android

Если требуется детальное понимание статусов модификации системы, на которой работает мобильное приложение. В протокол заложен механизм однозначного определения модификации устройства. Он состоит из двух переменных: ctsProfileMatch и basicIntegrity. Об их назначении — чуть ниже.

Остальные пункты в рамках этой статьи, на мой взгляд, менее интересны. Общий принцип такой: если вам нужно что-то очень точное или что-то, что обезопасит контент, — ищите другой (дополнительный) способ защиты. Аналогично в случае, когда вы не собираетесь реализовывать проверку в нормальном порядке, как это задумано протоколом, или ваше приложение опирается на созданные уязвимости в конфигурации устройства.

Схематично процесс проверки клиента можно представить в виде схемы:

Рассмотрим поэтапно процесс верификации устройств по протоколу:

Инициация процесса проверки со стороны клиента.Отправка запроса от клиента на Backend на генерацию уникального идентификатора проверки (nonce) сессии. В процессе выполнения запроса на сервере генерируется ключ (nonce) сессии, сохраняется и передаётся на клиент для последующей проверки.

Генерация JWS-токена на стороне удостоверяющего центра.Клиент, получив nonce, отправляет его на удостоверяющий центр вместе со служебной информацией. Затем в качестве ответа клиенту возвращается JWS, содержащий информацию о клиенте, время генерации токена, информацию о приложении (хеши сертификатов, которыми подписывается приложение в процессе публикации в Google Store), информацию о том, чем был подписан ответ (сигнатуру). О JWS, его структуре и прочих подробностях расскажу дальше в статье.

Затем клиент передаёт JWS в неизменном виде на Backend для проверки. А на стороне сервера формируется ответ с информацией о результате прохождения аттестации.После получения статуса проверки JWS на стороне сервера обычно сохраняют факт проверки и, опираясь на него, влияют на функциональность положительным или негативным образом. Например, клиентам, не прошедшим аттестацию, можно отключить возможность писать комментарии, голосовать за рейтинг, совершать иные активности, которые могут повлиять на качество контента приложения или создавать угрозу и неудобство другим пользователям.

Описание процесса верификации на стороне сервера JWS от удостоверяющего центра

Документация Google в рамках тестирования на сервере предлагает организовать online-механизм верификации JWS, при котором с сервера приложения отправляется запрос с JWS на удостоверяющий сервис Google. А в ответе от сервиса Google содержится полный результат проверки JWS.

Но данный метод проверки JWS для промышленного использования не рекомендуются. И даже больше: для каждого приложения существует ограничение в виде 10 000 запросов в сутки (подробнее об ограничениях — здесь), после которых вы выгребите квоту и перестанете получать от него вменяемый ответ. Только информацию об ошибке.

Далее расскажу обо всём алгоритме верификации JWS, в том числе о верификации самих сертификатов (проверке цепочки сертификатов).

Подробнее о JWS

JWS представляет собой три текстовых (base64 зашифрованных) выражения, разделенные точками (header.body.signature):

В данном примере после расшифровки base64 получим:

Header :

Body:

Signature

Остановимся на том, что именно содержится во всем JWS.

Header:

alg — алгоритм, которым зашифрованы Header и Body JWS. Нужен для проверки сигнатуры.

x5c — публичная часть сертификата (или цепочка сертификатов). Также нужен для проверки сигнатуры.

Читайте также:  Unity3d webview для андроид

Body:

nonce — произвольная строка полученная с сервера и сохранённая на нём же.

timestampMs — время начала аттестации.

apkPackageName — название приложения, которое запросило аттестацию.

apkDigestSha256 — хеш подписи приложения, которое загружено в Google Play.

ctsProfileMatch — флаг, показывающий прошло ли устройство пользователя верификацию в системе безопасности Google (основной и самый жёсткий критерий, по которому можно понять было ли устройство заручено и прошло ли оно сертификацию в Google).

apkCertificateDigestSha256 — хеш сертификата (цепочки сертификатов), которыми подписано приложение в Google Play.

basicIntegrity — более мягкий (по сравнению с ctsProfileMatch) критерий целостности установки.

Signature

Бинарная сигнатура, с помощью которой можно сделать заключение, что тело сообщения JWS было подписано с использованием сертификатов (цепочки сертификатов) указанных в Header, и с использованием известного нам приватного ключа. Ключевое — позволяет понять, что в цепочке взаимодействия нет никого, кроме нас и удостоверяющего центра Google.

Проверка сертификатов

Перейдём к непосредственной проверки каждой части полученного JWS. Начнём с сертификатов и алгоритма шифрования:

1. Проверяем, что алгоритм, с помощью которого подписано тело, нами поддерживается:

2. Проверяем, что сертификат (цепочка сертификатов), содержащиеся в Header (поле x5c), удовлетворяют нас по содержимому (загружаются в качестве публичных ключей):

3. Валидируем сигнатуру сертификата (цепочки сертификатов):

4. Сверяем hostname подписавшего сервера с сервером аттестации Google (ISSUINGHOSTNAME = ‘attest.android.com’):

Верификация тела JWS

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

1. Проверка nonce.

Тут все просто. Распаковали JWS, получили в Body nonce и сверили с тем, что у нас сохранено на сервере:

2. Проверяем заручено ли устройство, с которого происходит запрос.

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

Есть два параметра, на основе которых можно принимать решение о надежности устройства: ctsProfileMatch и basicIntegrity. ctsProfileMatch — более строгий критерий, он определяет сертифицировано ли устройство в Google Play и верифицировано ли устройство в сервисе проверки безопасности Google. basicIntegrity — определяет, что устройство не было скомпрометировано.

3. Проверяем время начала прохождения аттестации.

Тоже ничего сложного. Нужно проверить, что с момента ответа от сервера Google прошло немного времени. По сути, нет чётких критериев прохождения теста — с реферальным значением нужно определиться самим.

4. Проверяем подпись приложения.

Здесь тоже два параметра: apkDigestSha256 и apkCertificateDigestSha256. Но apkDigestSha256 самой Google помечен как нерекомендуемый способ проверки. С марта 2018 года они начали добавлять мета-информацию в приложения — из-за чего ваш хеш подписи приложения может не сходиться с тем, который будет приходить в JWS (подробнее — здесь).

Поэтому единственным способом проверки остается проверка хеша подписи приложения apkCertificateDigestSha256. Фактически этот параметр нужно сравнить с теми sha1 ключа, которым подписываете apk при загрузке в Google Play.

5. Проверяем имя приложения, запросившего аттестацию.

Сверяем название приложения в JWS с известным названием нашего приложения.

Верификация сигнатуры

Здесь нужно совершить одно действие, которое даст нам понимание того, что Header и Body ответа JWS подписаны сервером авторизации Google. Для этого в исходном виде склеиваем Header c Body (с разделителем в виде «.») и проверяем сигнатуру:

Читайте также:  Антивирус для андроид хонор

Вместо заключения. Библиотека на PHP

Уже после решения задачи и отдельно от нашей кодовой базы, я разработал библиотеку на PHP, которая обеспечивает полный цикл верификации JWS.

Её можно скачать из Packagist и использовать в своих проектах.

Источник

Исправить в Magisk «SafetyNet не пройден: несовпадение профиля CTS»

В данной статье мы попытались собрать абсолютно все способы решения проблемы в Magisk «SafetyNet не пройден: несовпадение профиля CTS».

Большинство пользователей которые ранее пользовались SuperSU переходят на новый Magisk, так как он имеет довольно множество плюшек, о которых мы говорили ранее.

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

Но многие пользователи, что установили Magisk Manager, столкнулись с проблемой «SafetyNet не пройден: несовпадение профиля CTS» и в этой статье мы предложим вариантов как ее исправить.

Инструкция как исправить:
«SafetyNet не пройден: несовпадение профиля CTS»
в Magisk

Ниже будут представлены 6 шагов для исправления «SafetyNet не пройден».

Шаг 1 — Избавиться от SuperSU

Если вы получали Root права с помощью ZIP файла SuperSU или CF Auto Root, который установил SuperSU на ваш Android, а после решили поменять на Magisk, то это может быть первой проблемой с SafetyNet.

Удалите SuperSu из вашего смартфона или планшета, а после прошить в Recovery файл UPDATE-unSU-signed.zip чтобы полностью вычистить все из системы.

Шаг 2 — Изменить режим SELinux

Попробуйте установить режим работы SELinux в «Permissive», а после вернуть обратно «Enforcing» и перезагрузить Android.

Шаг 3 — Отключить «отладку по USB»

Если у вас до последнего момента у вас была включена «отладка по USB«, тогда перейдите в меню «Настройки»-> «Для разработчиков» и отключить «отладку» и перезагрузить Android.

Шаг 4 — Используете другое ядро

Поищите в сети интернет стороннее ядро для своего Android, после чего проверьте не исчезла ли проблема в Magisk «SafetyNet не пройден: несовпадение профиля CTS».

Шаг 5 — Другие проблемы

Перейдите в меню настроек Magisk и отключите Busybox и Systemless hosts и перезагрузите Android.

Шаг 6 — включить режим Magisk Core Only Mode

Если все предыдущее шаги вам не помогли, тогда попробуйте включить режим работы Magisk Core Only Mode, который отключает дополнительные возможности Magisk.

Шаг 7 — добавить строки build.prop

С оригинальной прошивки (если вы используете кастом) в файле build.prop, который находиться в разделе /system, скопируйте поля со значения:

И добавьте их в файл build.prop установленной прошивки.

Шаг 8 — ввести команду в терминале

Установите приложение терминал на Android и введите в него следующие команды:

su
sh /magisk/.core/magiskhide/disable
sh /magisk/.core/magiskhide/enable

Шаг 9 — Начать все с начала

Если вам ничего не помогло, тогда попробуйте переустановить прошивку на вашим Android, а после получить Root с помощью Magisk, чтобы избавиться от проблемы «SafetyNet не пройден: несовпадение профиля CTS».

Остались еще вопросы? Пишите их в комментариях, рассказывайте, что у вас получилось или наоборот!

Вот и все! Больше статей и инструкций читайте в разделе Статьи и Хаки Android. Оставайтесь вместе с сайтом Android +1, дальше будет еще интересней!

Источник

Оцените статью