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

Как вы будете хранить секретные секретные данные в приложении iPhone?

Скажем, мне нужно получить доступ к веб-сервису из приложения iPhone. Эта веб-служба требует от клиентов цифровой подписи HTTP-запросов, чтобы доказать, что приложение "знает" общий секрет; клиентский ключ. Подпись запроса хранится в HTTP-заголовке, и запрос просто отправляется через HTTP (а не HTTPS).

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

Итак, как бы вы безопасно сохранили этот ключ, учитывая, что вам всегда говорили, что он никогда не хранит ничего чувствительного на стороне клиента?

Средний пользователь (99% пользователей) будет с радостью использовать приложение. Будет кто-то (враг?), Который хочет этого секретного ключа клиента, чтобы причинить вред сервису или клиенту в результате олицетворения. Такой человек может сделать джейлбрейк на своем телефоне, получить доступ к двоичному файлу, запустить "строки" или шестнадцатеричный редактор и сориться. Таким образом, просто хранить ключ в исходном коде - ужасная идея.

Другая идея - хранить ключ в коде, а не строковый литерал, но в NSMutableArray, созданный из байтовых литералов.

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

EDIT - поэтому я прочитал это о Keychain: "В iPhone OS приложение всегда имеет доступ к своим собственным элементам связки ключей и не имеет доступа к каким-либо другим элементам приложения. Система генерирует свой собственный пароль для keychain и сохраняет ключ на устройстве таким образом, что он недоступен для любого приложения."

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

EDIT - Отправленный отчет об ошибке # 6584858 на http://bugreport.apple.com

Спасибо.

4b9b3361

Ответ 1

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

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

Ответ 2

Цель, в конечном счете, ограничить доступ веб-службы к авторизованным пользователям, не так ли? Очень просто, если вы контролируете веб-службу (если нет - оберните ее в веб-службу, которую вы контролируете).

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

2) Пусть каждая копия приложения генерирует уникальный идентификатор. Как вы это делаете, зависит от вас. Например, вы можете создать его в исполняемый файл при загрузке (возможно ли это для приложений iPhone)? Вы можете использовать GUID телефона, предполагая, что у них есть способ его вычисления. Вы могли бы также переделать это за сеанс, если хотите.

3) Используйте открытый ключ для шифрования "Мой уникальный идентификатор - $FOO, и я одобрил это сообщение". Отправьте это с каждым запросом на веб-службу.

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

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

6) Постройте бизнес-процессы, чтобы удовлетворить необходимость: a) удалить доступ от пользователя, который злоупотребляет им, и b) восстановить доступ к пользователю, чей телефон был физически скомпрометирован (это будет очень, очень редко, если только пользователь является противником).

Ответ 3

UAObfuscatedString может быть решением вашей проблемы. Из документов:

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

Ответ 4

Если вы можете нести только iPhone OS 3.0, вы можете посмотреть push-уведомления. Я не могу вдаваться в подробности, но вы можете доставить полезную нагрузку на серверы Apple вместе с самим уведомлением. Когда они принимают предупреждение (или если ваше приложение работает), тогда вызывается часть вашего кода и сохраняется элемент keychain. На данный момент это единственный способ безопасного хранения секретного iPhone, о котором я могу думать.

Ответ 5

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

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

Stru Obfuscation (если ссылка прерывает поиск "Обфускация/Шифрование строки (NSString)" )

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

Лучше, чем ничего не делать.

Дэвид

EDIT: Я действительно использовал это в приложении. Я поместил строку базового кодирования в info.plist, затем выполнил несколько операций над ним в коде - rot13, повернул/инвертировал байты и т.д. Последняя обработанная строка использовалась для декодирования запутанной строки. Теперь три агентства письма наверняка сломают это, но при огромной стоимости много часов декодируют двоичный файл.

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

Ответ 6

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

Ответ 7

Вы рассмотрели/попробовали предложение Push Notification для первоначальной передачи секретного приложения и брелка? Или в конечном итоге найти какой-то другой метод для достижения этого?

Ответ 8

У меня будет приложение для загрузки приложений iphone на Amazon S3. Вместо того, чтобы вводить учетные данные AWS в приложении, у меня будет телефон приложения домой к моему серверу для URI и заголовков, которые будут использоваться в запросе на загрузку S3. Мой сервер будет генерировать URI S3, правильные подписи и т.д. Затем я смогу реализовать более жесткую и более конкретную модель безопасности в своем веб-сервисе приложения, чем сам AWS, и не выдавать мои ключи AWS всем, у кого есть взломанный iphone.

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

  • избегать глобальных учетных данных. сделать их для каждого пользователя/приложения
  • избегать постоянных учетных данных. сделайте их временными, если возможно
  • избегать глобальных разрешений. дайте им только необходимые разрешения. например, разрешения на запись могут быть разбиты на вставки, перезаписи, удаления, записи на группу ресурсов A или B и т.д., и чтение может быть разбито на чтение именованных ресурсов, чтение списка всех существующих ресурсов, чтение групп ресурсов A или B и т.д.

Ответ 9

Звучит неуклюже. Будет использовать HTTPS и, возможно, пакет шифрования для обработки ключа.

Я думаю, что CommonCrypto доступен для iPhone.

РЕДАКТИРОВАТЬ: По-прежнему звучит неуклюже. Зачем кому-то передавать секретный ключ в HTTP-заголовке? Любой, кто отслеживает ваш сетевой трафик (например, через маршрутизатор wifi для ведения журнала), будет видеть его.

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

ИЗМЕНИТЬ II: Я вижу. Я бы продолжил использовать брелок... Я думаю, что он предназначен только для таких случаев. Я пропустил, что вы генерировали запрос с помощью ключа. Я бы все же использовал HTTPS, если бы мог, так как вы не рискуете людьми, которые вывели вашу схему генерации ключей через проверку достаточного количества подписей.

Ответ 10

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