Безопасные ключи в сценарии App App, безопасно ли это?

Я пытаюсь скрыть 2 секрета, которые я использую в одном из моих приложений.

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

Я думал об этом сценарии -

  • Предварительно засев секреты в моем приложении CoreData Database, распространяя их в других сущностях, чтобы скрыть их. (У меня уже есть начальная БД в этом приложении).
  • Когда приложение запускается в первый раз, генерируйте и перемещайте ключи в связку ключей.
  • Удалить записи из CoreData.

Это безопасно или хакер может увидеть это и получить эти ключи?

* ТРЕТЬЕ РЕДАКТИРОВАНИЕ ** Извините, что не объяснил этот сценарий с самого начала - Приложение имеет много уровней, каждый уровень содержит файлы (аудио, видео, изображения). Пользователь может приобрести уровень (IAP), и после завершения покупки мне нужно загрузить файлы на свое устройство.

Для iOS6 файлы хранятся с новой функцией Apple "Hosted Content". Для iOS5 файлы хранятся в Amazon S3.

Таким образом, во всем этом процессе у меня есть 2 ключа: 1. Ключ IAP, для проверки покупки в Apple IAP. 2. Клавиши S3, для получения файлов от S3 для пользователей iOS5:

NSString *secretAccessKey = @"xxxxxxxxx";
NSString *accessKey = @"xxxxxxxxx";

Нужно ли вообще защищать эти ключи? Я боюсь, что люди смогут получить файлы с S3 без покупки уровней. Или что хакеры смогут создать взломанную версию со всеми предварительно загруженными уровнями внутри.

Ответ 1

Позвольте мне попытаться разбить ваш вопрос на несколько подвопросов/предположений:

Предположения:

а) Брелок - безопасное место

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

Вопросы:

а) Есть ли способ вставить ключ в приложение (двоичный файл, поставляемый из AppStore) и быть полностью защищенным?

Краткий ответ - НЕТ. Как только в вашем двоичном файле что-то есть, оно может быть переработано.

б) Поможет ли запутывание?

Да. Это увеличит время для хакера, чтобы понять это. Если ключи, имеющиеся у вас в приложении, будут "стоить" меньше, чем время, потраченное на реверс-инжиниринг - в общем, вы хороши.

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

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

в) Что мне делать в таком случае? *

Трудно дать вам хорошее решение, не зная предыстории того, что вы пытаетесь сделать.

Например, почему у всех должен быть доступ к одному и тому же Amazon S3? Нужно ли им только для чтения или писать (как указал Кендалл Хельмштеттер гейн).

Я считаю, что одним из наиболее безопасных сценариев было бы что-то вроде этого:

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

Таким образом вы защитите себя от множества возможных атак.

в) Ухххххххххххххххх... Есть ли что-нибудь попроще?

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

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

Постскриптум Кендалл и Роб правы.

Обновление 1 (на основе новой информации)

Прежде всего, вы видели в руководстве по программированию покупки приложений.

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

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

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

Это не остановит продвинутого хакера, но, по крайней мере, защитит от кого-то, кто использует iExplorer и просто копирует файлы (так как они будут зашифрованы).

Обновление 2

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

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

Ответ 2

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

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

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

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

Edit:

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

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

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

Ответ 3

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

Это не пустая трата времени, чтобы немного запутывать. Это здорово. Но не тратьте на это много времени. Если он в программе и очень ценен, то он будет взломан. Сосредоточьтесь на том, как определить, когда это произойдет, и как восстановить, когда это произойдет. И насколько это возможно, переместите такие конфиденциальные данные на какой-либо другой сервер, который вы контролируете.