Как безопасно отправить пароль через HTTP, используя Javascript при отсутствии HTTPS? - PullRequest
54 голосов
/ 05 января 2010

Самая основная проблема, с которой сталкиваются все разработчики: всякий раз, когда пользователь отправляет форму, пароль отправляется по сети, и он должен быть защищен. Сайт, для которого я разрабатываю, не имеет HTTPS. Владелец не хочет покупать SSL-сертификат и не заинтересован в самозаверяющем сертификате. Поэтому я хочу защитить пароль, отправленный через HTTP с использованием Javascript при отправке формы.

Чтобы заинтересовать downvoters: Как безопасно отправить пароль через HTTP? НЕ дает разумного решения, и я нахожусь в другой ситуации.

Если я использую MD5, можно изменить эту строку пароля. Что насчет nonce / HMAC? Любая доступная библиотека Javascript для этого? Или у вас есть предложение / подсказка для решения? Заранее спасибо!

Ответы [ 11 ]

77 голосов
/ 05 января 2010

Невозможно безопасно отправить пароль , который пользователь может проверить без SSL.

Конечно, вы можете написать некоторый JavaScript, который сделает пароль безопасным для передачи по проводной сети посредством хеширования или шифрования с открытым ключом. Но как пользователь может быть уверен в том, что сам JavaScript не был подделан посредником до того, как он достиг их, чтобы отправить пароль злоумышленнику вместо сайта или даже просто поставить под угрозу безопасность алгоритм? Единственным способом было бы, чтобы они были опытными программистами и заставляли их проверять каждую строку вашей страницы и сценария, чтобы убедиться, что они были кошерными, прежде чем вводить пароль. Это не реалистичный сценарий.

Если вы хотите, чтобы пароли были защищены от атак «человек посередине», вы должны купить сертификат SSL. Другого пути нет. Привыкай к этому.

Если я использую MD5, можно изменить эту строку пароля.

Нет ... по крайней мере, нетривиально. Хотя MD5 имеет атаки против него, это алгоритм хеширования и, следовательно, необратимый. Тебе придется его перебить.

Но, опять же, злоумышленнику не нужно смотреть на ваши MD5. Он может просто саботировать JavaScript, который вы отправляете пользователю для создания MD5.

24 голосов
/ 05 января 2010

Решение здесь заключается в том, чтобы вообще не отправлять пароль. Используйте вызов / ответ.

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

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

11 голосов
/ 05 января 2010

Если вы ДЕЙСТВИТЕЛЬНО хотите углубиться в это, посмотрите на обмен ключами Диффи-Хеллмана *1001*, который был создан, чтобы "позволить двум сторонам, которые не имеют предварительных знаний друг о друге, совместно установить общий секрет" ключ по небезопасному каналу связи "

Хотя я не специалист по криптографии, поэтому я не до конца знаю, действительно ли это безопасно, если у злоумышленника есть и клиент (исходный код JavaScript), и транспортный механизм (анализатор пакетов)

5 голосов
/ 05 января 2010

Вы можете использовать реализацию RSA javascript для шифрования пароля перед отправкой. (Вот пример RSA в Javascript .)

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

4 голосов
/ 05 января 2010

К сожалению, невозможно обеспечить безопасность незашифрованного запроса. Любой, у кого есть доступ к вашему javascript, сможет просто перепроектировать его / подделать, а любой, у кого есть анализатор пакетов, сможет наблюдать за незашифрованным трафиком. Эти два факта вместе означают:

Нет SSL? Нет безопасности.

1 голос
/ 05 января 2010

Если у вас нет доступа к SSL, MD5 должен быть достаточным для предотвращения случайного обнаружения паролей (например, в файле сетевого журнала или чем-то еще). Все остальное было бы пустой тратой времени. Просто убедитесь, что приложение не предоставляет доступ к конфиденциальной информации (например, номера кредитных карт, истории болезни и т. Д.).

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

1 голос
/ 05 января 2010

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

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

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

1 голос
/ 05 января 2010

Не думаю, что проблема здесь в технологии, а в том, как вы объясняете важность SSL. Предоставьте им надежные материалы для чтения, я уверен, что в Интернете их много.

1 голос
/ 05 января 2010

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

0 голосов
/ 09 декабря 2015

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

Я думаю, что наиболее безопасный способ, вместо того, чтобы хранить H ( пароль ), где H - выбранная вами хеш-функция, хранить g ^ H ( пароль ), т.е. использовать пароль в качестве личного ключа для обмена ключами Диффи-Хеллмана. (Возможно, вам также следует использовать случайный g для разных пользователей - это становится вашей солью.) Затем для проверки вы генерируете одноразовый номер b, отправляете пользователя g ^ b и вычисляете (g ^ H ( пароль) )) ^ б. Пользователю не нужно знать g - ему нужно только вычислить (g ^ b) ^ H ( пароль ) = (g ^ H ( пароль )) ^ b. Теперь у вас есть число, которое обе стороны знают если , пользователь ввел правильный пароль, и построение доказательства с нулевым знанием ответа на запрос-ответ, основанного на знании правильного числа, тривиально, тогда как случайное число, используемое в качестве сервера «закрытый ключ» делает этот подход невосприимчивым к атакам воспроизведения.

...