Ответ 1
Использование HTTP с SSL сделает вашу жизнь намного проще, и вы можете спокойно чувствовать себя очень умными людьми (умнее меня хотя бы!) тщательно изучили этот метод конфиденциального общения в течение многих лет.
Если на экране входа пользователь отправляет форму со своим именем пользователя и паролем, пароль отправляется простым текстом (даже с POST, исправьте меня, если я ошибаюсь).
Итак, вопрос в том, как правильно защитить пользователя и его пароль от третьей стороны, которая могла бы подслушивать данные связи?
Я знаю, что HTTPS является решением проблемы, но есть ли способ обеспечить по крайней мере некоторый уровень безопасности с использованием стандартного HTTP-протокола (запрос POST)? (возможно, с помощью javascript)
ИЗМЕНИТЬ Возможно, я забыл некоторые важные вещи.
Я был о странице - это страница с PHP, созданная для входа в систему, которая, конечно же, отправляется пользователю в HTTP GET-запросе в виде HTML файла. Соединение между сервером и клиентом не установлено (@Jeremy Powel), поэтому я не могу создать такой протокол установления связи. И я хочу, чтобы весь процесс был прозрачным для пользователя - он хочет отправить пароль, а не заниматься криптографией.
Спасибо.
Использование HTTP с SSL сделает вашу жизнь намного проще, и вы можете спокойно чувствовать себя очень умными людьми (умнее меня хотя бы!) тщательно изучили этот метод конфиденциального общения в течение многих лет.
Безопасная аутентификация - это широкая тема. В двух словах, как упоминалось в @jeremy-powell, всегда рекомендуется отправлять учетные данные через HTTPS вместо HTTP. Это уберет много головных болей, связанных с безопасностью.
Сертификаты TSL/SSL в наши дни довольно дешевы. На самом деле, если вы не хотите тратить деньги вообще, существует бесплатный letencrypt.org - автоматический центр сертификации.
Вы можете сделать еще один шаг и использовать caddyserver.com, который вызывает letencrypt в фоновом режиме.
Теперь, как только мы спустим HTTPS...
Вы не должны отправлять логин и пароль через POST или GET. Вместо этого используйте заголовок авторизации (основная схема аутентификации доступа), которая построена следующим образом:
- Имя пользователя и пароль объединяются в строку, разделенную двоеточие, например: имя пользователя: пароль
- Полученная строка кодируется с использованием вариант RFC2045-MIME Base64, за исключением, не ограничиваясь этим, 76 char/линия.
- Метод авторизации и пробел, то есть "Базовый", тогда положить перед закодированной строкой.
источник: Википедия: заголовок авторизации
Это может показаться немного сложным, но это не так. Там есть много хороших библиотек, которые предоставят вам эту функцию из коробки.
Есть несколько веских причин, по которым вы должны использовать заголовок авторизации
https://user:[email protected]/login
(например, Chrome автоматически преобразует его в заголовок Authorization
) ВАЖНО:
Как отметил @zaph в своем комментарии ниже, отправка конфиденциальной информации как запроса GET - это не очень хорошая идея, поскольку она, скорее всего, попадет в журналы сервера.
Вы можете использовать схему ответа на вызов. Скажите, что клиент и сервер знают секрет S. Тогда сервер может быть уверен, что клиент знает пароль (не отдавая его):
Edit:
Здесь есть проблема со свежестью R и тем фактом, что HTTP не имеет гражданства. Это может быть вызвано тем, что сервер создает секрет, назовите его Q, что знает только сервер. Затем протокол будет выглядеть следующим образом:
Следует отметить, что, поскольку H (R, Q) не может быть подделана клиентом, H (R, Q) действует как файл cookie (и поэтому может быть фактически реализован как файл cookie).
Другое Редактировать:
Предыдущее редактирование протокола неверно, поскольку любой, кто наблюдал H (R, Q), похоже, может воспроизвести его с правильным хешем. Сервер должен помнить, какие R уже не свежие. Я CW'ing этот ответ, поэтому вы, ребята, можете отредактировать это и разработать что-то хорошее.
Если ваш веб-хостинг позволяет это, или вам нужно будет работать с конфиденциальными данными, тогда используйте HTTPS, точка. (Это часто требуется по закону afaik).
В противном случае, если вы хотите сделать что-то через HTTP. Я бы сделал что-то подобное.
Таким образом, пароль защищен, и тот же хэш аутентификации не может быть воспроизведен.
О безопасности токена сессии. Это немного сложнее. Но это может сделать повторное использование украденного токена сессии немного сложнее.
Таким образом, если маркер сеанса был украден, и кто-то еще отправил запрос, то при следующем запросе исходного пользователя сеанс будет уничтожен. Так что, если пользователь активно просматривает сайт, часто нажимая на ссылки, то похититель далеко не уйдет с украденным токеном. Эту схему можно укрепить, потребовав другую аутентификацию для чувствительных операций (например, удаление учетной записи).
РЕДАКТИРОВАТЬ: Обратите внимание, что это не предотвращает атаки MITM, если злоумышленник создает свою собственную страницу с другим открытым ключом и отправляет запросы прокси на сервер. Для защиты от этого открытый ключ должен быть закреплен в локальном хранилище браузера или в приложении, чтобы обнаруживать подобные уловки.
О реализации: RSA, вероятно, наиболее известный алгоритм, но он довольно медленный для длинных ключей. Я не знаю, насколько бы быстрой была реализация PHP или Javascript. Но, вероятно, есть более быстрые алгоритмы.
Я бы использовал серверную систему обмена ключами Diffie-Hellman на стороне сервера и на стороне клиента с AJAX или несколькими формами (я рекомендую первый), хотя я не вижу никаких хороших реализаций в Интернете. Помните, что JS-библиотека всегда может быть повреждена или изменена MITM. Локальное хранилище может использоваться для борьбы с этим, в какой-то степени.
Вы можете использовать SRP для использования защищенных паролей по небезопасному каналу. Преимущество состоит в том, что даже если злоумышленник обнюхивает трафик или компрометирует сервер, они не могут использовать пароли на другом сервере. https://github.com/alax/jsrp - это библиотека javascript, которая поддерживает защищенные пароли через HTTP в браузере или на стороне сервера (через node).
HTTPS настолько мощный, что использует асимметричную криптографию. Этот тип криптографии позволяет не только создавать зашифрованный туннель, но и проверять, что вы разговариваете с нужным человеком, а не с хакером.
Вот исходный код Java, который использует асимметричный шифр RSA (используемый PGP) для связи: http://www.hushmail.com/services/downloads/
вы можете использовать ssl для своего хоста, есть бесплатный проект для ssl, например letencrypt https://letsencrypt.org/