Подводные камни идентификации Android-устройства +5




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

Гугл говорит, что идентифицировать устройство очень просто. Но мы же говорим об Android:)

Данная статья ориентирована на приложения или библиотеки, которые не хотят привязываться к гугловым сервисам.

Итак, давайте погрузимся в это чудесное приключение по получению уникального идентификатора устройства.

Тут мы видим несколько путей:


  • Advertising ID
  • IMEI
  • MAC-address
  • Serial Number
  • Android ID

Выглядит пока что не плохо, не так ли? Целых пять способов получить уникальный идентификатор для Android-устройства. Я уверена, что если вы еще пошуршите по сети, то, наверняка, найдете еще парочку других способов, но тут я вынесла самые популярные. Итак, давайте пойдем по порядку.

Advertising ID


Это уникальный для пользователя рекламный идентификатор, предоставляемый службами Google Play. Он необходим для работы рекламы, чтобы Google понимал, какую рекламу можно показывать конкретному пользователю и какая реклама уже была показана с помощью встроенных в приложения рекламных баннеров. А так же это значит, что вы лишитесь этого идентификатора, если ваше приложение будет скачано, к примеру, с Amazon, а помимо этого вам придется втащить в ваше приложение гугловые библиотеки.

dependencies {
    compile 'com.android.support:appcompat-v7:21.0.3'
    compile 'com.google.android.gms:play-services:6.5.87'
}

Вывод: мы не идентифицируем устройство во всех случаях.

Но мы же хотим наверняка, верно? Тогда идем дальше.

IMEI


Это международный идентификатор мобильного оборудования, используемый на телефонах стандарта GSM. Номер IMEI используется сетями для идентификации смартфонов и блокировки доступа в сеть украденных или занесенных в черный список девайсов. Но к сожалению с IMEI может возникнуть ряд проблем:


<uses-permission android:name="android.permission.READ_PHONE_STATE" />

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            String imei = telephonyMgr.getImei();
} else {
            String imei = telephonyMgr.getDeviceId();
}

Вывод: мы не идентифицируем устройство во всех случаях и нас еще и могут обмануть:C

MAC-address


Не надежно 100%. Гугл сам об этом говорит, но, к сожалению, я действительно встречала пару приложений, которые полагались на MAC-address устройства. Не делайте так.
It may be possible to retrieve a Mac address from a device’s WiFi or Bluetooth hardware. We do not recommend using this as a unique identifier. To start with, not all devices have WiFi. Also, if the WiFi is not turned on, the hardware may not report the Mac address.

Serial Number


Считается уникальным серийным номером устройства, который остается с ним до “самого конца”. Получить его можно таким способом:

//Until Android 7.1 (SDK 25)
Build.SERIAL
//Android 8 (SDK 26) ++
Build.getSerial()

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

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

Android ID


— Вот оно! — должны завопить мы. — Решение всех наших бед!

Android ID — это тоже уникальный идентификатор устройства. Представляет из себя 64-разрядную величину, которая генерируется и сохраняется при первой загрузке устройства.
Получить его можно вот так:

Secure.getString(getContentResolver(), Secure.ANDROID_ID);

Казалось бы, такая короткая строчка избавляет нас от головной боли по идентификации устройства. Даже ребята из гугл использую Android_ID для LVL в примере.

И тут наши надежды рушатся и ничто уже не будет прежним. После обновления на Android 8 Android_ID теперь стал уникальным для каждого установленного приложения. Но, помимо этого, гугл ведь заботится о нас, так что приложения, которые были установлены до обновления останутся с прежними одинаковыми идентификаторами, которые гугл сохраняет с помощью специально написанного для этого сервиса. Но если приложение будет удалено, а затем заново установлено — Android_ID будет разным. Для того чтобы это не произошло, нужно использовать KeyValueBackup.


Но этот backup сервис нужно зарегистрировать, еще и package name указать. Более того, в документации написано, что это может не сработать по любой причине. И кто в этом виноват? Да никто, просто вот так.

Общий вывод


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

P.S. Все подборки я публикую как всегда в телеграм канале miproblema, а ссылку можно найти в моем профиле, либо найти в поиске телеграм по названию.

С наступающим:)

Вы можете помочь и перевести немного средств на развитие сайта



Комментарии (26):

  1. Sabubu
    /#19565410

    Получить id очень просто: при первом запуске генерируете случайное число и сохраняете в папку приложения. Вот и id.

    Я вообще не понимаю, почему все эти идентификаторы доступны приложениям. Они должны быть с самого начала не доступны, а если приложения на них полагаются, то должны генерироваться фейковые id.

    В Линуксе какие-то аппаратные идентификаторы могут быть в /sys или /proc, думаю, на Андроиде так же.

    • miproblema
      /#19565418

      А если пользователь удалит приложение? А если пользователь запретит write external storage?

      • Sabubu
        /#19566012

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

        • bessovesti
          /#19567354 / +1

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

          • advance
            /#19567840

            Для этого есть Play Services. Всё, что за пределами Google Play, существенной прибыли не приносит, потому не критично

        • advance
          /#19567866

          Доступ то есть. Но ведь подобное- требования заказчика. Чего хочет или не хочет пользователь не волнует никого

  2. APXEOLOG
    /#19565450

    А почему-бы не использовать старую добрую регистрацию с логином и паролем? Если пользовать хочет сохранить свои данные у вас на серверах — он зарегистрируется

    • miproblema
      /#19565464

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

      • APXEOLOG
        /#19565516 / -1

        а если его пароль и логин украдут?

        А если его телефон украдут?


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

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


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

        • miproblema
          /#19565540

          А если его телефон украдут?

          Его нужно для начала разлочить, а потом войти в приложение, где тоже может быть пароль. И человек скорее всего заметит, что у него украли девайс, у него будет время заблокировать акк.
          Неужели в андроиде нету возможности приложениям коммуницировать друг с другом?

          Есть, content provider. Можно решить эту проблему таким образом, да. Но если приложение одно и его удалили, потом, когда его вновь поставят нельзя легко понять, что оно на этом девайсе уже было.
          А если мы говорим совсем серьезно — вы никак не защититесь от мультиакка, если человек захочет этим заниматься.

          Довольно популярное мнение в последнее время:) Действительно, зачем ставить забор, если его можно переехать танком:))

          • APXEOLOG
            /#19565598

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

            А если у него телефон без лока?


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

    • Sovigod
      /#19565488 / +1

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

      • Sabubu
        /#19566024

        Возможность отслеживания пользователя после удаления приложения должна отсутствовать по соображениям приватности. Если вы боитесь злоупотреблений, берите плату за регистрацию. Или спрашивайте email.

        • Sovigod
          /#19566078

          Так мне не нужно после удаления. Мне нужно после повторной установки узнать что этот пользователь мне уже знаком.
          Если он удалит и не установит — я буду только рад.
          email/sms — достать временные в интернете стоит чуть менее чем ничего.
          Плата за регистрацию? — без комментариев.

          • Sabubu
            /#19566320

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

            • Sovigod
              /#19566384

              Это не любопытство. Пользователь зарегестировался и принял условия пользования моего приложения. И там есть разрешение собирать его ПД с девайса. А кто-то согласился и с GDPR.
              Ну и условия использования моего приложения не позволяют им пользоваться приватно. Не устраивают условия — попрошу на выход.
              Пользователь может запросить удаление своих ПД у нас в соответствии с законом указанным Вами. И тогда мы их удалим.

            • Protos
              /#19567862

              А есть кстати требования государства по выявлению мошенничества и идентификаторов устройства, если в политике пдн четко прописана цель почему нет?

            • advance
              /#19567878

              Сервис дает знать, что обрабатывает ПД, имеет политику конфидециальности. Если Вы не готовы поделиться данными, то с Вами сервис работать не будет.

              Нельзя принудить оказывать услуги тому, кому их оказывать не хотят. За исключением монополии и прочего.

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

  3. Sovigod
    /#19565498

    >> Но если приложение будет удалено, а затем заново установлено — Android_ID будет разным
    Это реально проверяли? В документации по другому написано. Для смены нужен factory reset или смена APK signing key

    • miproblema
      /#19565508

      Проверка производилась на Nexus 5X. Не все приложения привязаны к гугловым сервисам. Использовали factory reset. Так что в любом случае идентифицировать однозначно нельзя.

      • Garrett
        /#19566348

        В принципе это они правильно сделали что Android_ID меняется при Factory Reset, потому что дальше может быть уже другое физ-лицо пользоваться устройством (продан, подарен, и т.д.)

        А нельзя ли запросить данные учётки Google привязанной к телефону? Вопрос конечно что делать если учётка не привязана, но там и Google Play Store и сервисов не будет конечно.

      • khim
        /#19567894

        Ну слава богу хоть после Factory Reset ничего нельзя идентифицировать. Иначе вообще бред получается: Factory Reset должен сделать телефон «как новый» и готовый к продаже — а тут кто-то будет знать что и когда я на нём устанавливал. Непорядок.

  4. enginegl
    /#19565690 / +1

    Advertising ID любой пользователь может легко сбросить через настройки Google на устройстве.

    • Sabubu
      /#19566032

      И это хорошо. Не должно быть неизменяемых идентификаторов и возможности слежки за пользователем.

  5. DmitryKolpo
    /#19567358 / +1

    Дополнение(предостережение) к Advertising ID:
    если испольтзовать этот id и в прайваси полиси ничего не указать, то гугл через некоторое время удалит приложение из гугл стора

  6. advance
    /#19567856

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

    Мне, как и многим, тоже не нравится идея однозначной идентификации девайса или пользователя по девайсу. Но тут вопросы не к автору, а к бизнесу. Почти всегда подобное- требование заказчика\работодателя. При том не все и не всегда понимают, что это по сути- тоже ПД. А недавние скандалы об утечках показали что бывает с ПД когда их собирают.

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

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

    В ином случае- это к лучшему, что Google не оставили решения этого вопроса.