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

Обеспечение связи [Подлинность, конфиденциальность и целостность] с мобильным приложением?

Приложение Android/Iphone будет получать доступ к данным приложения с сервера. [Django-Python]

Как я могу защитить связь с мобильным приложением?

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

Мои требования:

  • Аутентификация [Разрешено только приложение]
  • Целостность [Сообщения не должны изменяться между ними]
  • Конфиденциальность [Коммуникация не должна читаться, если флиртовать]

Мое усилие:

  • SSL аутентифицирует только сервер, а не клиент.
  • Я не могу использовать симметричное шифрование [Предоставляет только конфиденциальность]
  • Цифровая подпись невозможна [Lacks Privacy]
  • PGP заполняет все 3 требования.

Проблема:

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

Итак, как я могу двигаться дальше? Как индустрия справляется с этим?

Должен ли я реализовать случайный подход:

  • Использовать простой SSL и перекрещивать пальцы?, поскольку аутентификация невозможна, если ключи украдены? (Возможно только аутентификация сервера)

Update:

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

4b9b3361

Ответ 1

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

Вот высокоуровневый подход. Создайте сертификат SSL с самозаверяющим сервером и разверните его на своем веб-сервере. Если вы используете Android, вы можете использовать keytool, входящий в комплект Android SDK для этой цели; если вы используете другую платформу приложений, например, iOS, для них существуют аналогичные инструменты. Затем создайте самозаверяющий клиент и разверните его в своем приложении в пользовательском хранилище ключей, включенном в ваше приложение, в качестве ресурса (keytool также будет генерировать это приложение). Настройте сервер, требующий аутентификации на стороне клиента, и только принять сертификат клиента, который вы создали. Настройте клиента для использования этого сертификата на стороне клиента для идентификации себя и принимайте только тот серверный сертификат, который вы установили на своем сервере для этой части.

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

Шаг за шагом для этого является гораздо более длинным ответом, чем это требуется здесь. Я бы предложил сделать это поэтапно, так как в Интернете есть ресурсы о том, как работать с самоподписанным SSL-сертификатом как на Android, так и на iOS, как на сервере, так и на стороне клиента. В моей книге также есть полная прогулка, Безопасность приложений для платформы Android, опубликованная O'Reilly.

Ответ 2

SSL имеет двухстороннюю аутентификацию, как уже упоминалось другими комментаторами. Но я не думаю, что вы даже должны пытаться аутентифицировать клиента, например приложение. Вы только аутентифицируете пользователя (владельца ресурса в терминах Oauth), а не агента или клиента.

Это факт, что мобильные приложения не могут хранить никаких секретов. Поэтому никогда не ставьте сертификаты/пароли на устройство. Типичным плохим примером было бы сохранить имя пользователя и пароль в каком-то системном хранилище ключей, таком как keychain IOS. Если пользователь приложения не устанавливает пароль на телефоне, все хранилище ключей сохраняется в виде обычного текста, и каждый может сбрасывать всю информацию. Вставить сертификат в приложение почти так же плохо, как в отличие от сервера, мобильный телефон не заблокирован в компьютерном зале. Люди теряют их.

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

Oauth 2.0 Непосредственный поток предназначен для решения этой проблемы. Однако, это далеко не идеально. И есть некоторые фундаментальные проблемы с Oauth 2.0 spec. В частности, для реализации этого потока приложение должно использовать UIWebView (встроенный браузер), который сам по себе может быть небезопасным и плохой пользовательский интерфейс. Таким образом, это в значительной степени устраняет все потоки, основанные на перенаправлении. Единственное хорошо известное приложение, использующее перенаправление OAuth 2, - это facebook, и его сделано плохо.

OAuth 2.0 Resource Owner - один из вариантов. Благодаря этому потоку ваш уровень безопасности всей системы может быть таким же высоким, как и решение B2C - решение для онлайн-банкинга на основе браузера. Это означает, что любой пользователь с паролем имени пользователя сможет получить доступ к ресурсам на сервере - тот же уровень безопасности для решения на основе браузера.

Тем не менее, вам все равно нужно быть осторожным, как упоминалось ранее, спецификация OAuth 2 имеет некоторые фундаментальные проблемы - в этом случае вы не можете следовать ее спецификации для реализации логики обновления токена, которая обычно включает использование никогда- expire refreshing token - который можно рассматривать как реализацию Google OAuth 2. Затем этот токен становится тайной - проигрывает цель использования OAuth.

Одним из способов является автоматическое обновление маркера на основе последнего действия.

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

Вот почему банки платят миллионы за свое мобильное банковское решение, и все же они все еще терпят неудачу (http://hothardware.com/News/Mobile-Banking-Apps-for-iOS-Vulnerable-to-Man-in-the-Middle-Attacks/) ; -)

Ответ 3

Использовать аутентификацию клиента с помощью SSL или просто накладывать собственную аутентификацию клиента (имя пользователя/пароль, токен и т.д.) поверх SSL-аутентификации сервера.

(Edit: Перемещение комментария здесь, так как оно не подходит в качестве комментария)

Чтобы разработать немного, любая информация аутентификации должна быть сохранена или введена в приложение. Если вы каждый раз вводите пароль, вам не нужно его сохранять, но это явно неудобно. Вы можете зашифровать его с помощью определенного для устройства ключа, чтобы он не отображался на корневых устройствах. С помощью закрытого ключа вам необходимо либо защитить его с помощью введенного пользователем пароля (см. Выше), либо защитить его системой. Это доступно только с Android 4.0 (ICS) с открытым API-интерфейсом в хранилище ключей системы KeyChain. В этом случае пользователю необходимо разблокировать (используя шаблон/пароль или PIN-код) для доступа к хранилищу ключей.