Проверка того, что сообщение пришло из определенного приложения/конечной точки

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

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

Существует несколько вариантов использования такого рода проверки, например:

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

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

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

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

Некоторые идеи, которые я рассмотрел: -

  • SSL — хорошо работает для защиты канала и предотвращения несанкционированного доступа (что соответствует некоторым требованиям), но все же не может гарантировать целостность источника данных.

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

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

  • Хэш-цепочка. Это показалось очень интересным способом использования -time для проверки каждой полезной нагрузки данных от клиента к серверу, но опять же это зависит от того, что само приложение не декомпилируется, потому что пароль все еще должен храниться приложением.

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


person Jonathan Ellis    schedule 18.12.2012    source источник
comment
Как насчет использования nonce, сгенерированного сервером для идентификации транзакций? Используйте GCM или что-то еще, чтобы убедиться, что только устройство может получить одноразовый номер.   -  person Raghav Sood    schedule 18.12.2012
comment
Неплохая идея задействовать GCM, но мы предполагаем, что нет другого способа получать сообщения GCM, кроме как через приложение Android... Может быть, и есть (я не знаю). В любом случае, было бы неплохо, если бы мы смогли найти решение (если оно существует), которое не зависит от технологий, специфичных для платформы.   -  person Jonathan Ellis    schedule 18.12.2012
comment
Возможно, вы захотите попробовать security.stackexchange.com. Я не эксперт по криптографии, но там много.   -  person Raghav Sood    schedule 18.12.2012
comment
Связано: stackoverflow.com/questions/8950732/security-from-evil- пользователь   -  person finnw    schedule 19.12.2012
comment
Вам может быть интересно это.   -  person Bruno    schedule 20.12.2012


Ответы (1)


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

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

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

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

person Nikolay Elenkov    schedule 19.12.2012
comment
Я думаю, что OP хочет запретить пользователю, у которого есть законные учетные данные, использовать их со сторонним клиентским приложением, что не совсем то же самое. - person finnw; 19.12.2012
comment
Мне это так не кажется, но тем не менее. Почему люди продолжают закрывать совершенно правильные вопросы? Потому что на них может быть трудно ответить? Действительно? - person Nikolay Elenkov; 20.12.2012
comment
1. ОП упомянул о жестком кодировании ключа в приложении, поэтому, даже если они реализуют ваше предложение, им все равно придется добавить DRM, чтобы ключ было труднее извлечь. 2. Не уверен, что этот вопрос адресован мне (я не голосовал за закрытие как оффтоп. Хотя голосование за обман может быть оправдано). - person finnw; 20.12.2012
comment
Заключительные вопросы не были адресованы конкретно вам. В последнее время я вижу много совершенно правильных вопросов. «Сообщения из приложения могут быть проверены как отправленные самим приложением» в моей книге означает, что он хочет аутентифицировать приложение. DRM обычно относится к привязке контента к одному (или небольшому количеству устройств). «Контент» здесь может быть ключом, если вы читаете его широко, но это не меняет того факта, что он хочет аутентифицировать приложение («убедиться, что источником сообщений является само приложение» ). Я не говорю, что дал идеальный ответ, просто некоторые идеи. - person Nikolay Elenkov; 20.12.2012