Безопасность веб-API - PullRequest
       6

Безопасность веб-API

14 голосов
/ 14 января 2010

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

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

Будет больше приложений, обращающихся к API.

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

так ... какие варианты у меня есть?

Я уверен, что безопасное соединение (SSL) в данный момент мне недоступно, но, тем не менее, это не поможет мне в решении проблемы декомпиляции, не так ли?


EDIT

Сначала я этого не говорил, но у пользователя не будет запрашиваться имя пользователя / пароль . Это приложение (я) должны быть аутентифицированы, а не пользователи приложения (ов).

Ответы [ 4 ]

20 голосов
/ 15 января 2010

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

Запрос подписи

Самым распространенным методом проверки запросов API является подписей запросов . Как правило, перед отправкой запроса на API-сервер параметры в запросе сортируются, и в смесь добавляется уникальный ключ. Вся партия затем используется для создания хэша, который добавляется к запросу. Например:

public static function generateRequestString(array $params, $secretKey)
{
    $params['signature'] = self::generateSignature($params, $secretKey);
    return http_build_query($params,'','&');
}

public static function generateSignature($secretKey, array $params)
{
    $reqString = $secretKey;
    ksort($params);
    foreach($params as $k => $v)
    {
        $reqString .= $k . $v;
    }
    return md5($reqString);
}

Вы можете создать строку запроса API, используя приведенный выше код, просто вызвав метод generateRequestString() с массивом всех параметров, которые вы хотите отправить. Секретный ключ - это то, что уникально предоставляется каждому пользователю API. Обычно вы передаете свой идентификатор пользователя на сервер API вместе с подписью, а сервер API использует ваш идентификатор для извлечения вашего секретного ключа из локальной базы данных и проверки запроса так же, как вы его создали. Предполагая, что ключ и идентификатор пользователя верны, этот пользователь должен быть единственным, кто сможет сгенерировать правильную подпись. Обратите внимание, что ключ никогда не передается в запросе API.

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

Временные ключи

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

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

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

Основная информация

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

8 голосов
/ 14 января 2010

Я бы порекомендовал вам проверить OAuth. он определенно должен помочь вам разобраться в проблемах безопасности с инструментами авторизации для доступа к вашему API.

http://oauth.net

3 голосов
/ 14 января 2010

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

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

http://www.codeproject.com/KB/security/SecureStream.aspx

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

0 голосов
/ 14 января 2010

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

Для решения проблемы декомпиляции вы хотели бы сохранить хэш пароля в API, а не исходный пароль. Смотрите объяснение здесь: http://phpsec.org/articles/2005/password-hashing.html.

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