Как хранить критически важную информацию, такую ​​как секрет, ключ, токен, encryptionKey, в приложении iOS

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

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

В приложении для iOS у нас есть следующая возможность хранить информацию.

  1. UserDefault: не подходит для этого случая.
  2. Строка Константа: не подходит для этого случая. Может быть реконструирован для получения или просто использовать команда строк
  3. Защищенная база данных: хранить в защищенной зашифрованной базе данных. Но опять же, вы обязаны защитить имя пользователя и пароль базы данных.
  4. KeyChain: лучше всего хранить важную информацию. Но мы не можем сохранить информацию до установки приложения. Чтобы сохранить в цепочке для ключей, нам сначала нужно открыть приложение, прочитать из какого-либо источника и сохранить в цепочке для ключей. Не подходит и для нашего случая.
  5. Константа настраиваемой строки хеширования: чтобы напрямую не использовать секрет, токен, ключ от поставщика услуг (mixpanel, PayPal), вместо этого используйте хеш-версию этой информации из настраиваемого ключа. Это тоже не идеальное решение. Но добавить сложности во время взлома.

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


person Rajan Twanabashu    schedule 30.03.2017    source источник
comment
Я не знаю решения без участия сервера. В конце концов, вам всегда понадобится какой-то секрет (закрытый ключ, секретный хеш и т. Д.), Чтобы расшифровать любую информацию, которую вы вводите в свое приложение. Единственный известный мне способ обеспечить, чтобы эта информация доходила до вашего приложения, и только ваше приложение использует Apple Push-уведомления, поскольку эта служба гарантирует, что только доверенная конечная точка может получить ваши полезные данные. К сожалению, это требует, чтобы пользователь включил push-уведомления для вашего приложения.   -  person dirkgroten    schedule 30.03.2017
comment
может быть один вариант.   -  person Rajan Twanabashu    schedule 30.03.2017
comment
Было бы хорошо, если бы iOS и Android предоставили для этого собственные средства (например, дополнительную зашифрованную полезную нагрузку, которую приложение извлекает из магазина приложений, где вы, как разработчик, имеете контроль), которые могут быть расшифрованы только самим приложением и не могут быть доступ через двоичный пакет.   -  person dirkgroten    schedule 30.03.2017
comment
Вот чего я жду. А пока мы, кстати, делаем небезопасные приложения.   -  person Rajan Twanabashu    schedule 30.03.2017
comment
Может, это сработает? Предоставьте секрет своему приложению в виде бесплатного контента для покупок внутри приложения, размещенного в магазине приложений. когда он доставлен (безопасно магазином приложений, только на устройства без взлома) в приложение, перенесите его в связку ключей. Плюсы: его нет в вашем приложении при первоначальном распространении, поэтому его сложнее обнаружить, для магазина приложений требуется устройство без джейлбрейка. Минусы: сложнее быстро изменить секрет для всех ваших установок, даже бесплатная покупка в магазине приложений может потребовать аутентификации пользователя, что затрудняет UX.   -  person Lobsterman    schedule 07.04.2017
comment
^ атрибуция: 1. stackoverflow.com/questions/4015163/ 2. stackoverflow.com/questions/36465226/   -  person Lobsterman    schedule 07.04.2017
comment
Кроме того, если вы выберете путь обфускации, эта библиотека покажется весьма эффективной: github.com/UrbanApps/UAObfuscatedString   -  person Lobsterman    schedule 07.04.2017


Ответы (6)


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

Основные ресурсы по запросу

Доступ и загрузка ресурсов по запросу

person Michał Myśliwiec    schedule 11.04.2017
comment
Могут ли эти секреты, скажем, ключ API, быть защищены от злоумышленника, который управляет приложением, и эти секреты хранятся в их связке ключей? - person xref; 23.04.2020

1) Требуется подключение к Интернету

1.1) Push-уведомления. Отличным способом безопасного обмена данными может быть использование (тихих) push-сервисов от Apple, которые используют apns и отправляют данные через https - подробнее 3.1

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

Оборотная сторона: требуется рабочее сетевое соединение, и в основном информация поступает в приложение, когда оно уже выполняется => кажется, не подходит для вашего случая. (см. шаг 4)

2) Статические данные (поскольку без сетевого подключения / коммуникационного партнера обмен не будет)

Шифрование данных с помощью закрытого ключа, предоставляемого в самом пакете. Будь то строка или хеш, который можно реконструировать с помощью функций, которые вы внедрили в свое приложение. Начиная с iOS9, довольно сложно декомпилировать приложения iOS, и в основном вы будете в основном смотреть в предоставленные файлы заголовков. Поэтому, если у вас была такая функция, строка, хеш-значение или что-то еще, убедитесь, что вы поместили ее в свой .m-файл!

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

Подходит для шифрования: iOS System.Security https://developer.apple.com/reference/security или просто openssl

Разница между описанным вами подходом к связке ключей заключается в следующем: у вас есть значение, которое БУДЕТ зашифровано и надежно сохранено. (2) описывает подход к зашифрованному и хранимому (в связке) полубезопасному значению, которое БУДЕТ расшифровываться.

3) Обмен информацией

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

3.1 Расширенный безопасный обмен информацией - Silent Push Используйте серверы Apple для обмена своими секретами с этой целью. Если вам просто нужно обмениваться небольшими порциями данных. Я бы рекомендовал использовать тихие push-уведомления для пользователя, они работают даже без явного разрешения пользователя. Огромное преимущество: в случае изменения ваших секретов или ключей вы можете как можно скорее сообщить пользователям об изменении. Скорее всего, им потребуется изменение только тогда, когда они получат новые данные, которые в большинстве случаев должны надежно работать. Исключение: обмен данными в локальных сетях или через bluetooth, в этом случае я бы рекомендовал предоставить пользователю уведомление о необходимости обновить локальный ключ дешифрования. Или обменяйте ключ в этом же формате. Еще раз: я утекаю некоторую подробную информацию об архитектуре вашей среды. Оборотная сторона: вы не знаете, использовал ли пользователь ваше приложение в первый раз, пока пользователь не «скажет» вам об этом. https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1

3.1 Расширенный безопасный обмен информацией - покупка в приложении Используйте бесплатную покупку в приложении, чтобы пользователь мог получить данные на свой телефон. Хороший момент: вы можете легко предоставлять большие фрагменты данных, так как это должен быть активный запрос пользователя, пользователь ожидает определенное время обработки и также должен знать, что требуется рабочее подключение к Интернету. Обратная сторона: пользователю придется выбрать это специально. Раньше приложение не работало должным образом. https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction.html#//apple_ref/doc/uid/TP40008267

Таким образом, он лишь незначительно отличается от подхода (2) по своей основной идее.

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

Здесь нужна дополнительная информация :-)

Я хотел бы еще раз подчеркнуть, что приложение на iOS уже не так просто расшифровать, даже декомпиляция не даст всего, как вы ожидаете. Например, инструменты дешифрования, такие как dumpdecrypt, работали должным образом только до iOS 8.4.

person Lepidopteron    schedule 30.03.2017

Мне кажется, что лучший способ сделать это - использовать встроенный CloudKit. Вы можете сохранить свои секреты на панели управления CloudKit, а затем получить их при запуске. Поскольку CloudKit - это только транспортный уровень, вам придется хранить секреты приложения в KeyChain.

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

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

Подробнее о CloudKit

person derickito    schedule 08.02.2018

Cocoapods-keys может быть лучшим вариантом.

Из cocoapods-keys документа

Имена ключей хранятся в ~ / .cocoapods / keys /, а значения ключей - в цепочке ключей OS X. Когда вы запускаете установку модуля или обновление модуля, создается класс Objective-C с зашифрованными версиями ключей, что затрудняет простой сброс содержимого расшифрованного двоичного файла и извлечение ключей. Во время выполнения ключи расшифровываются для использования в вашем приложении.

Сгенерированные классы Objective-C хранятся в каталоге Pods / CocoaPodsKeys, поэтому, если вы проверяете свою папку Pods, просто добавьте Pods / CocoaPodsKeys в свой файл .gitignore. CocoaPods-Keys поддерживает интеграцию в проекты Swift или Objective-C.

Перейдите по этой ссылке для установки, использования и получения дополнительной информации: https://github.com/orta/cocoapods-keys

person Ravi    schedule 13.04.2017
comment
Кажется, это новый подход. Обязательно проверю. - person Rajan Twanabashu; 13.04.2017
comment
Вы нашли какое-нибудь (другое) решение? - person Ravi; 14.04.2017

Я согласен с @Lobsterman и считаю, что лучше всего будет использовать их комбинацию.

  • Не включайте изначально секретную информацию в приложение.
  • Доставьте секретный ключ в виде контента для покупки в приложении, ресурса по запросу или отправьте его через push-уведомление. Это позволит вам периодически менять ключ, если вы хотите, и изменение вступит в силу без каких-либо дополнительных усилий.
  • Добавьте запись в доступ к связке ключей после доставки контента.
person JIthin    schedule 11.04.2017

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

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

person msmq    schedule 11.04.2017