Подтвердить что ты не робот

Как сервер может аутентифицировать приложение iPhone (код, а не пользователь)?

Скажем, у меня есть решение с приложением iPhone, которое генерирует некоторую информацию, а затем отправляет эту информацию в веб-службу для обработки. Важно, чтобы ТОЛЬКО запросы от экземпляров данного приложения iPhone разрешалось обрабатывать (может быть много примеров приложения, используемого многими разными пользователями, но я хочу быть уверенным, что все они используют код, которому я доверяю). Другими словами, я хочу быть уверенным, что мое приложение для iPhone не может (легко) выдаваться другим клиентам. Как вы это сделаете?

4b9b3361

Ответ 1

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

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

Учтите также, что если вы можете избежать "воспроизводимой" атаки на безопасность, вам будет лучше. Другими словами, если кто-то нарушает ваше приложение/протокол, а данные для других людей делают это одинаково для каждой копии/экземпляра, тогда у вас больше проблем, потому что инструкции/ключи можно просто отправить в Интернет где-то. Если вы можете определить способ сделать каждый экземпляр/клиент уникальным, то вы можете наблюдать на сервере и в худшем случае обрезать известных сломанных клиентов и т.д. (Это сложно на платформе iPhone.)

Ответ 2

Другая возможность - запросить приложение для некоторой части содержимого пакета приложений - что-то вроде байта 59967 исполняемого приложения или включенного plist или xib. Сохраняя как имя файла, так и позицию, заданную абсолютно случайным образом, любой спуфинг должен вставлять всю копию вашего приложения, что позволяет очень легко определить, запутывают ли они ваше приложение и, возможно, очень легко google для событий.

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

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

В принципе, больше слоев, а не один действительно жесткий слой - это то, что вы хотите в обеспечении чего-то.

Ответ 3

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

Если этот ответ слишком короткий/абстрактный, оставьте комментарий, и я объясню более подробно.

Edit:

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

Ответ 4

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

То, что вы ищете, - это обеспечение подлинности. Вы можете сделать что-то вроде выполнения обмена ключами DH (http://en.wikipedia.org/wiki/Diffie-Hellman_key_exchange), чтобы генерировать общий секрет (так как жестким кодированием секрет в вашем приложении не гарантирует его тайну), а затем используя этот секрет для выполнения определенных манипуляций с вашим сообщением (хотя это еще не идеальная аутентичность).

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

Возможно, Грэхем Ли появится и даст лучший ответ.:)

ИЗМЕНИТЬ

(думая вслух). Вот идея: после того, как ваше приложение находится в магазине, вы можете извлечь подпись кода приложения для публикации, поместить его на свой сервер и использовать его в запросе-ответе. Когда ваш клиент подключается к серверу, ваш сервер может генерировать случайное значение и отправлять его обратно. Клиент может манипулировать этим значением, используя встроенную подпись кода приложения, и вернуть управляемое значение. Между тем, ваш сервер может делать то же самое. Когда сервер получает управляемое значение, он может сравнить его с его версией, а затем прекратить/продолжить соединение в зависимости от того, совпадают ли они. Технически это все равно может быть подделано (другое приложение может украсть подпись кода и использовать его самостоятельно), но похоже, что это будет более безопасно.

Ответ 5

Я задал подобный вопрос некоторое время назад:

Ограничение доступа к серверу для приложения iPhone

В результате я создал случайное имя пользователя (GUID). Затем я беру имя пользователя, добавляю секрет (жестко закодированный в моем приложении, отраженный на сервере) и SHA1, и отправляю его как пароль.

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

Другим подходом было бы отправить сертификат SSL-клиента с вашим пакетом приложений и настроить сервер только для приема соединений от клиентов с этим сертификатом.

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

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

Ответ 6

Используйте свой идентификатор устройства... Отправьте идентификатор устройства с запросом... каждый iphone будет иметь уникальный идентификатор устройства

Ответ 7

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