Как мне убедиться, что мой REST API отвечает только на запросы, сгенерированные доверенными клиентами, в моем случае мои собственные мобильные приложения? Я хочу предотвратить нежелательные запросы, поступающие из других источников. Я не хочу, чтобы пользователи вводили серийный ключ или что-то еще, это должно происходить негласно, после установки и без какого-либо вмешательства пользователя.
Насколько я знаю, HTTPS предназначен только для проверки сервера, с которым вы общаетесь, и того, о ком он говорит. Я, конечно, собираюсь использовать HTTPS для шифрования данных.
Есть ли способ сделать это?
Обновление: пользователь может выполнять действия только для чтения, которые не требуют входа пользователя в систему, но они также могут выполнять действия записи, которые требуют входа пользователя в систему (аутентификация по токену доступа). В обоих случаях я хочу, чтобы API отвечал на запросы, поступающие только от надежных мобильных приложений.
API также будет использоваться для регистрации новой учетной записи через мобильное приложение.
Обновление 2: кажется, что есть несколько ответов на этот вопрос, но я, честно говоря, не знаю, какой из них помечать как ответ. Некоторые говорят, что это может быть сделано, некоторые говорят, что это невозможно.
Ответы:
Вы не можете
Вы никогда не сможете проверить сущность, любую сущность , будь то личность, аппаратный клиент или программный клиент. Вы можете только проверить, что то, что они говорят вам, правильно, а затем принять честность .
Например, как Google узнает, что я захожу в свою учетную запись Gmail? Они просто спрашивают у меня имя пользователя и пароль, проверяют это , а затем принимают честность, потому что кто еще будет иметь эту информацию? В какой - то момент Google решил , что это не было достаточно , и добавил поведенческой проверки (ищет странное поведение) , но по - прежнему полагаться на человека , чтобы сделать поведение , то проверка на поведение .
Это то же самое, что и проверка клиента. Вы можете проверить только поведение Клиента, но не самого Клиента.
Таким образом, с помощью SSL вы можете проверить, есть ли у клиента действующий сертификат или нет, поэтому можно просто установить приложение, получить сертификат и запустить весь новый код.
Итак, вопрос: почему это так важно? Если это реальная проблема, я бы поставил под сомнение ваш выбор толстого клиента. Возможно, вам следует использовать веб-приложение (чтобы вам не пришлось выставлять свой API).
См. Также: Отказ от проверки SSL-сертификатов для приложений Android
и: Насколько безопасны клиентские SSL-сертификаты в мобильном приложении?
источник
Я уверен, что вам удобно работать с логинами пользователей и связью через SSL, поэтому я сосредоточусь на том, что, на мой взгляд, является более интересной частью вопроса: как обеспечить, чтобы ваши действия только для чтения - у которых не требуется пользователю для аутентификации - принимаются только от ваших собственных приложений клиента?
Прежде всего, есть обратная сторона, на которую fNek намекал в предыдущем ответе - ваши клиентские приложения находятся в руках потенциально враждебных пользователей. Они могут быть проверены, их сообщения проверены, их код разобран. Ничто из того, что я собираюсь предложить, не позволит вам гарантировать, что кто-то не будет перепроектировать ваш клиент и злоупотреблять вашим REST API. Но это должно поставить барьер перед любыми случайными попытками.
В любом случае, общий подход:
например, представьте
GET
запрос на/products/widgets
Допустим, секрет клиента - "OH_HAI_I_IZ_SECRET"
Объедините HTTP-глагол, и URL, и секрет:
И возьмите SHA-1 хэш этого:
Затем отправьте это вместе, чтобы запрос был для:
Наконец, чтобы кто-то не мог, по крайней мере, воспроизвести отдельные запросы, возьмите также временную метку и добавьте ее к параметрам и хешу. например, прямо сейчас, во времени Unix, это 1384987891. Добавьте это к объединению:
Хеш что:
И отправить:
Сервер проверит хеш, а также удостоверится в том, что временная метка является текущей (например, в течение 5 минут, чтобы учесть, что часы не идеально синхронизированы)
Предупреждение! Поскольку вы говорите о мобильных приложениях, существует определенный риск, что у чьего-то телефона будут неправильные часы. Или часовой пояс неправильный. Или что-то. Добавление времени к хешу, вероятно, нарушит работу некоторых законных пользователей, поэтому используйте эту идею с осторожностью.
источник
Всем, кто интересуется, на Android вы МОЖЕТЕ убедиться, что полученный вами запрос был отправлен из вашего приложения.
Короче говоря, когда вы загружаете свое приложение в Google, вы подписываете его уникальным ключом, который известен только вам (и Google).
Процесс проверки проходит (ish) так:
полный блог, который объясняет это и как его реализовать, можно найти здесь: http://android-developers.blogspot.co.il/2013/01/verifying-back-end-calls-from-android.html
источник
Итак, стоит упомянуть, прежде чем я начну, что для большинства приложений это сильно излишне. Для большинства случаев использования достаточно иметь один действительный сертификат и / или токен. Если для этого требуется что-то сложное, например, декомпиляция приложения, то даже большинство хакеров не будут беспокоиться, если вы не предоставите очень ценные данные. Но где же веселье в этом ответе?
Так что вы можете настроить асимметричную криптографию, похожую на цифровую подпись, используемую для подписи программ. Каждое приложение может иметь отдельный сертификат, который выдается одним ЦС и проверяется при подключении вашего пользователя. (либо при первой регистрации, либо при первой установке). Когда этот сертификат аутентифицирован, вы можете дополнительно обезопасить свое приложение, зарегистрировав этот сертификат как действительный для одного данного идентификатора устройства (такого как Android ID )
источник
Как отметил @Morons в своем ответе, очень сложно проверить сущность на другом конце соединения.
Самый простой способ обеспечить некоторый уровень аутентичности - заставить сервер проверить секрет, который знает только реальный объект. Для пользователя это может быть имя пользователя и пароль. Для программного обеспечения, в котором нет пользователя, вы можете встроить секрет.
Проблема этих подходов заключается в том, что вы должны доверять клиенту. Если кто-то перепроектирует ваше приложение или украдет ваш пароль, он может притвориться вами.
Вы можете предпринять шаги, чтобы затруднить извлечение секретной информации, запутав ее в исполняемом файле. Такие инструменты, как ProGuard, который является обфускатором для Java, могут помочь с этим, я не знаю так много о запутывании в других языках, но, вероятно, есть подобные инструменты. Использование соединения TLS помогает предотвратить слежку за вашим трафиком, но не предотвращает MITM-атаку. Пиннинг может помочь решить эту проблему.
Я работаю в компании под названием CriticalBlue (полное раскрытие!), У которой есть продукт под названием Approov, который пытается решить эту проблему доверия. В настоящее время он работает для Android / iOS и предоставляет механизм для проверки целостности клиентского приложения на наших серверах. Это достигается за счет того, что клиент рассчитывает ответ на случайный вызов. Клиент должен рассчитать ответ, используя атрибуты установленного пакета приложения, которые трудно подделать, и он включает в себя некоторые сложные механизмы предотвращения несанкционированного доступа.
Он возвращает токен, который вы затем можете отправить в качестве доказательства подлинности вашему API.
Важным отличием этого подхода является то, что хотя можно было бы отключить проверку подлинности на клиенте, в противном случае вы не получили бы маркер аутентификации, но вам необходимо проверить свое приложение на сервере. Библиотека также тесно связана с характеристиками исполняемого файла, в котором она находится, поэтому было бы очень трудно встроить ее в поддельное приложение и заставить его работать.
Существует анализ затрат / выгод, который должен сделать любой разработчик API, чтобы определить, насколько вероятно, что кто-то попытается взломать его API и насколько это может быть дорогостоящим. Простая секретная проверка в приложении предотвращает тривиальные атаки, но защитить себя от более решительного злоумышленника, вероятно, значительно сложнее и потенциально дорого.
источник
SSL защитит канал связи.
Успешный вход в систему выдаст токен аутентификации по зашифрованному соединению.
Токен аутентификации будет передан вашему REST API во всех последующих запросах.
источник
Это не будет слишком безопасно, но вы можете добавить какой-нибудь секретный код или даже подпись dgital. Недостаток: он должен быть включен в приложение, что облегчает его получение, если вы знаете, что делаете.
источник
Фактически, вы можете использовать SSL для аутентификации как клиента, так и сервера. Или, по-другому, «да, вы можете использовать клиентские сертификаты».
Вам нужно будет ...
Мобильное приложение может хранить сертификат в любом месте. Поскольку вам нужна аутентификация для конкретного приложения, вам следует рассмотреть возможность хранения сертификата в защищенном месте на диске (в Android вы можете создать таблицу «config» в вашей базе данных SQLite, а также строку для вашего сертификата и еще одну строку для вашего личного ключа). ,
источник