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

#android #api #authentication #google-api #client-server

#Android #API #аутентификация #google-api #клиент-сервер

Вопрос:

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

Я хочу быть уверен, что API могут использовать только те, кто прошел проверку подлинности на моих серверах.

Я могу дать им имя пользователя или пароль для использования API, но что, если кто-то другой использует имя пользователя и пароль и отправит тот же запрос на мой сервер (ответная атака). Как я могу избежать этой атаки на мой API?

Я видел, что Google использует ключ API в своих API, подобных direction, который связан с дайджестом ключа подписи; но я не уверен, как это работает и может ли что-то подобное помочь мне или нет?

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

Комментарии:

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

2. злоумышленник может использовать имя пользователя и пароль вашего пользователя, чтобы вы могли предотвратить это. man in the middle attack это то, что вы хотите?

3. Мы прошли man в середине с шифрованием отправляемого содержимого. Но предположим, что кто-то декомпилирует мобильное приложение, находит имя пользователя и пароль и отправляет новый запрос в мое приложение, используя имя пользователя и пароль — на самом деле я хочу быть уверенным, что клиентское приложение, которое запрашивает у меня, — это то же приложение, которое я сам разработал (а не другое приложение, которое декомпилировало мое приложение).код и перекомпилировал его)

4. если кто-то декомпилирует приложение, он может просто увидеть содержимое на этом конкретном устройстве, которое, безусловно, является его собственным устройством. он собирается украсть свой собственный пароль от имени пользователя, который уже есть?

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

Ответ №1:

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

полного способа обеспечить это не существует, но некоторые шаги могут обеспечить отличную защиту:

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

2- вы должны проверить свой код sdk (файл aar, который вы сказали) и извлечь из него имя пользователя и пароль разработчиков, aar чтобы разработчикам не нужно было знать о кодах внутри aar, как показано ниже:

YourSdkMainClass theInstance = YourSdkMainClass.getInstance(«имя пользователя», «пароль»);

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

4- на стороне сервера вы должны проверить полученное имя пакета и сравнить его с именем пакета (или списком имен пакетов), разрешенным для этого конкретного разработчика. если все в порядке, тогда ответьте на вызов API (или отправьте токен обратно)

ПРИМЕЧАНИЕ: этот сценарий можно улучшить, отправив подпись APK вместо packageName. используя ключ подписи, несколько приложений с одинаковым именем пакета не смогут отправить запрос на сервер. конечно, вам нужно иметь подпись APK ваших разработчиков на стороне сервера (спросите их, когда вы хотите предоставить им пароль пользователя)

но все это идеально, если вы тщательно проверяете aar .

Комментарии:

1. APK или библиотека proguard также могут быть перепроектированы. Представьте, что кто-то декомпилирует arr (или, в аналогичном случае, apk) и находит логику aar, а затем воссоздает другой aar, точно такой же, как мой arr. У злоумышленника также есть имя пользователя и пароль (путем декомпиляции приложения разработчика, который использует my aar), чтобы он мог отправить поддельный запрос на сервер

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

3. если человек, использующий ваш sdk, пытается атаковать, он может использовать тот же apk и подпись, потому что вы его впустили. это лучший способ ограничить атаку. не существует такого механизма, чтобы впустить кого-то, а затем сказать «нет», вы не можете использовать этот API таким образом. ваш уровень API (серверный код) должен быть настолько безопасным сам по себе.

4. сценарий, который я дал, состоит в том, чтобы просто убедиться, что некоторые конкретные packagename и signature используют ваши API, но на самом деле эти концепции непрактичны. вы либо позволяете кому-то использовать API, либо нет. если apk должен быть проверен, у него есть только один идентификатор, и это подпись apk 😉