Как бы вы держали секретные данные в секрете в приложении для iPhone? - PullRequest
37 голосов
/ 13 февраля 2009

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

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

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

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

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

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

РЕДАКТИРОВАТЬ - поэтому я прочитал об этой цепочке для ключей: «В iPhone OS приложение всегда имеет доступ к своим собственным элементам цепочки для ключей и не имеет доступа к элементам других приложений. Система генерирует свой собственный пароль для цепочки для ключей, и хранит ключ на устройстве таким образом, чтобы он был недоступен для любого приложения. "

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

РЕДАКТИРОВАТЬ - Поданный отчет об ошибке # 6584858 в http://bugreport.apple.com

Спасибо.

Ответы [ 10 ]

9 голосов
/ 13 февраля 2009

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

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

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

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

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

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

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

7 голосов
/ 05 ноября 2009

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

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

4 голосов
/ 14 августа 2014

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

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

2 голосов
/ 13 октября 2011

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

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

Запутывание строк (если разрывается ссылка, найдите "Obfuscate / Encrypt a String (NSString)")

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

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

David

РЕДАКТИРОВАТЬ: Я на самом деле использовал это в приложении. Я поместил базовую строку кодирования в список info.plist, затем сделал несколько операций над ней в коде - rot13, байт поворота / инвертирования и т. Д. Окончательно обработанная строка использовалась для декодирования запутанной строки. Теперь трехбуквенные агентства наверняка могут это сломать - но огромными затратами на многочасовое декодирование двоичного файла.

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

2 голосов
/ 17 июня 2009

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

0 голосов
/ 13 мая 2010

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

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

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

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

0 голосов
/ 18 февраля 2009

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

0 голосов
/ 13 февраля 2009

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

0 голосов
/ 13 февраля 2009

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

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

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

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

РЕДАКТИРОВАТЬ II: Ах, я вижу. Я бы пошел дальше и использовал брелок ... Я думаю, что он предназначен именно для таких случаев. Я пропустил, что вы генерировали запрос, используя ключ. Если бы я мог, то все равно использовал бы HTTPS, так как таким образом вы не рискуете, что люди выведут вашу схему генерации ключей на основе проверки достаточного количества подписей.

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