Мне предлагается написать веб-API для приложения (исполняемый файл, а не веб-приложение ), что позволит отправлять электронные письма.
Пользователь нажимает что-то, приложение связывается с API, который генерирует электронное письмо и отправляет его.
Я должен удостовериться, что никто из несанкционированных пользователей не получит доступ к API, поэтому мне нужно сделать некоторую аутентификацию, и у меня нет идеи, как это сделать правильно.
Будет больше приложений, обращающихся к API.
Первая мысль была – отправить имя пользователя и пароль, но это не решит проблему. Потому что, если кто-то декомпилирует приложение, они будут иметь URL-адрес запроса и переменные, включая пользователя / пароль, или просто его можно просто понюхать.
так … какие у меня варианты?
Я уверен, что безопасное соединение (SSL) в настоящее время недоступно мне, но все же это не поможет мне в решении проблемы декомпиляции, не так ли?
РЕДАКТИРОВАТЬ
Я не сказал об этом, но пользователь не будет запрашивать имя пользователя / пароль . Это приложение (приложения), которое должно быть аутентифицировано, а не пользователи приложений (приложений).
Я бы порекомендовал вам проверить OAuth. он определенно поможет вам разобраться в проблемах безопасности с авторизацией инструментов для доступа к вашему API.
Распределение вашего программного обеспечения действительно является основной проблемой. Хеширование имен пользователей и паролей и их сохранение в программном обеспечении не более полезно, чем хранение не хэшированных значений, так как любой из них будет работать для доступа к серверу 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.
Кто-то всегда будет в состоянии декомпилировать и охотиться за переменными. Обфускатор может скрыть их немного лучше. Sniffing также легко без SSL, если вы не используете частный и открытый набор ключей для шифрования клиентской части данных запроса и расшифровки серверной части (но, очевидно, этот ключ будет храниться в клиентском приложении).
Лучшее, что вам нужно сделать, это предоставить столько уровней защиты, сколько вам нужно, создание безопасного подключения и обфускацию вашего кода. Вы можете посмотреть следующую статью, которая демонстрирует безопасное соединение без использования SSL:
http://www.codeproject.com/KB/security/SecureStream.aspx
Как упоминалось в описании mattjames , вы никогда не должны хранить пароли в текстовом формате. Когда пользователь вводит свой пароль в приложение, храните хеш пароля. Тот же хеш должен храниться на сервере. Таким образом, если хеш рассматривается перехватчиком, они, по крайней мере, не будут видеть исходный пароль пользователя.
Вам нужно будет использовать SSL, если вам нужно, чтобы люди не видели простой текстовый пароль, который отправляется из приложения через сеть в API.
Для проблемы декомпиляции вы хотите сохранить хэш пароля в API, а не оригинальный пароль. См. Объяснение здесь: http://phpsec.org/articles/2005/password-hashing.html .