Я заметил, что большинство сайтов отправляют пароли в виде обычного текста по HTTPS на сервер. Есть ли преимущество, если вместо этого я отправлю на сервер хеш пароля? Было бы безопаснее?
Я заметил, что большинство сайтов отправляют пароли в виде обычного текста по HTTPS на сервер. Есть ли преимущество, если вместо этого я отправлю на сервер хеш пароля? Было бы безопаснее?
Ответы:
Это старый вопрос, но я почувствовал необходимость высказать свое мнение по этому важному вопросу. Здесь так много дезинформации
OP никогда не упоминал об отправке пароля в открытом виде через HTTP - только HTTPS, но многие, похоже, по какой-то причине отвечают на вопрос об отправке пароля через HTTP. При этом сказано:
Я считаю, что пароли никогда не следует сохранять (не говоря уже о передаче) в виде обычного текста. Это означает, что они не хранятся на диске или даже в памяти.
Люди, отвечающие здесь, похоже, думают, что HTTPS - это серебряная пуля, но это не так. Однако это, безусловно, очень помогает, и его следует использовать в любом сеансе аутентификации.
На самом деле нет необходимости знать, что такое исходный пароль. Все, что требуется, - это надежный способ сгенерировать (и надежно повторно сгенерировать) «ключ» аутентификации на основе исходного текста, выбранного пользователем. В идеальном мире этот текст должен немедленно генерировать «ключ», хешируя его с использованием необратимой соли. Эта соль должна быть уникальной для создаваемых учетных данных пользователя. Этот «ключ» будет тем, что ваши системы используют в качестве пароля. Таким образом, если ваши системы когда-либо будут скомпрометированы в будущем, эти учетные данные будут полезны только против вашей собственной организации и нигде больше, где пользователь ленился и использовал тот же пароль.
Итак, у нас есть ключ. Теперь нам нужно удалить любые следы пароля на клиентском устройстве.
Затем нам нужно получить этот ключ к вашим системам. Никогда не следует передавать ключ или пароль «в открытом виде». Даже по HTTPS. HTTPS не является непроницаемым. Фактически, многие организации могут стать доверенным MITM - не с точки зрения атаки, а для выполнения проверок трафика для реализации своих собственных политик безопасности. Это ослабляет HTTPS, и это не единственный способ, которым это происходит (например, перенаправление на HTTP-атаки MITM). Никогда не думайте, что это безопасно.
Чтобы обойти это, мы хэшируем ключ с помощью одноразового одноразового номера. Этот одноразовый номер уникален для каждой отправки ключа в ваши системы - даже для одних и тех же учетных данных в течение одного сеанса, если вам нужно отправить его несколько раз. Вы можете отменить этот одноразовый номер, когда он поступит в ваши собственные системы, для восстановления ключа аутентификации и аутентификации запроса.
На этом этапе я бы необратимо хешировал его в последний раз, прежде чем он навсегда сохранится в ваших собственных системах. Таким образом, вы можете поделиться "солью" учетных данных с партнерскими организациями для целей SSO и т.п., в то же время имея возможность доказать, что ваша собственная организация не может выдавать себя за пользователя. Лучшая часть этого подхода заключается в том, что вы никогда не делитесь ничем, созданным пользователем без его разрешения.
Проведите больше исследований, поскольку это еще не все, что я раскрыл, но если вы хотите обеспечить настоящую безопасность своим пользователям, я думаю, что этот метод в настоящее время является наиболее полным ответом здесь.
TL; DR:
Используйте HTTPS. Надежное хеширование паролей, необратимое, с уникальной солью для каждого пароля. Сделайте это на клиенте - не передавайте их фактический пароль. Передача исходного пароля пользователя на ваши серверы никогда не бывает «ОК» или «Хорошо». Удалите все следы исходного пароля. Используйте одноразовый номер независимо от HTTP / HTTPS. Это намного безопаснее на многих уровнях. (Ответ на ОП).
Поскольку это по HTTPS, это определенно нормально, чтобы отправить пароль без хеширования (по HTTPS это не простой текст). Кроме того, если ваше приложение зависит от HTTPS для обеспечения безопасности своего содержимого, тогда бесполезно хешировать пароль перед его отправкой по HTTPS (т.е. если злоумышленник может расшифровать данные на проводе, вы в любом случае облажались)
Нет, на самом деле это была бы уязвимость. Если злоумышленник может получить хэш из базы данных, он может использовать его для аутентификации, не взламывая его. Ни при каких обстоятельствах пользователь или злоумышленник не может получить хеш-пароль.
Весь смысл хеширования паролей состоит в том, чтобы добавить дополнительный уровень безопасности. Если злоумышленник может получить хэш и соль из базы данных с помощью SQL-инъекции или небезопасной резервной копии, он должен найти простой текст путем грубой силы. John The Ripper обычно используется для взлома хэшей паролей.
Отказ от использования https является нарушением OWASP Top 10: A9-Недостаточная защита транспортного уровня
РЕДАКТИРОВАТЬ:
если в своей реализации вы вычисляете a, sha256(client_salt+plain_text_password)
а затем вычисляете другой хэш на стороне сервера, sha256(server_salt+client_hash)
это не является серьезной уязвимостью. Однако он по-прежнему подвержен перехвату и воспроизведению запроса. Таким образом, это все еще явное нарушение WASP A9. Однако в качестве уровня безопасности по-прежнему используется дайджест сообщения.
Самое близкое, что я видел к замене https на стороне клиента, - это различие в обмене ключами в javascript . Однако это предотвращает активные атаки MITM и, таким образом, по техническим причинам является нарушением OWASP A9. Авторы кода согласны с тем, что это не полная замена HTTPS, однако это лучше, чем ничего и лучше, чем система хеширования на стороне клиента.
Отправка хеша по сети полностью сводит на нет цель хеширования, потому что злоумышленник может просто отправить хеш и забыть о пароле. Короче говоря, система, которая аутентифицирует использование хэша в открытом тексте, широко открыта и может быть скомпрометирована ничем иным, как сетевым сниффингом.
Пароль в виде открытого текста никогда (даже при использовании HTTPS) не покидает клиента. Он должен быть необратимо хеширован перед тем, как покинуть клиент, поскольку серверу не нужно знать фактический пароль.
Хеширование с последующей передачей решает проблемы безопасности для ленивых пользователей, которые используют один и тот же пароль в разных местах (я знаю, что это так). Однако это не защищает ваше приложение как хакера, получившего доступ к базе данных (или каким-либо другим способом заполучившего хэш), поскольку хакер может просто передать хеш и заставить сервер его принять.
Чтобы решить эту проблему, вы, конечно, можете просто хешировать полученный сервером хэш и завершить его.
Мой подход к проблеме в веб-приложении на основе сокетов, которое я создаю, заключается в том, что при подключении к клиенту сервер генерирует соль (случайную строку, добавляемую перед хешированием) и сохраняет ее в переменной сокетов, а затем передает этот хеш клиенту. Клиент берет пароль пользователя, хеширует его, добавляет соль с сервера и хеширует все это перед передачей на сервер. Затем он отправляется на сервер, который сравнивает этот хеш с хешем (хеш в БД + соль). Насколько я знаю, это хороший подход, но, честно говоря, я мало читал по этой теме, и если я ошибаюсь в чем-то, я хотел бы исправить это :)
Используйте HTTP-дайджест - он защищает пароль даже через http (но лучше всего использовать http-дайджест через https)
Википедия:
Аутентификация доступа к дайджесту HTTP - это один из согласованных методов, которые веб-сервер может использовать для согласования учетных данных с веб-пользователем (с использованием протокола HTTP). Дайджест-проверка подлинности предназначена для замены незашифрованного использования проверки подлинности с базовым доступом, позволяя безопасно установить личность пользователя без необходимости отправки пароля в виде открытого текста по сети. Дайджест-аутентификация - это, по сути, применение криптографического хеширования MD5 с использованием значений nonce для предотвращения криптоанализа.
Ссылка: http://en.wikipedia.org/wiki/Digest_access_authentication
Если вы хотите увидеть использование в «реальной жизни», вы можете посмотреть на phpMyID - провайдер php openid, который использует дайджест-аутентификацию http http://siege.org/phpmyid.php
.. или вы можете начать с образцов php auth на http://php.net/manual/en/features.http-auth.php
Дайджест http rfc: http://www.faqs.org/rfcs/rfc2617
Судя по моим тестам, все современные браузеры его поддерживают ...
Если вы хотите заменить пароль в открытом виде по HTTPS на хешированный пароль по HTTP, тогда у вас возникнут проблемы. HTTPS генерирует случайный общий ключ транзакции при открытии канала связи. Это сложно взломать, так как вы в значительной степени ограничены перебором общего ключа, используемого для (относительно) краткосрочной транзакции. В то время как ваш хэш можно просто понюхать, отключить и просмотреть в радужной таблице или просто перебрать в течение длительного времени.
Однако простое обфускация пароля на стороне клиента (не хэш), отправляемая по HTTPS, имеет определенное значение. Если не ошибаюсь, эту технику действительно используют некоторые банки. Целью этого метода не является защита пароля от перехвата через провод. Скорее, это делается для того, чтобы пароль не использовался глупыми шпионскими инструментами и плагинами браузера, которые просто захватывают каждый запрос HTTPS GET / POST, который они видят. Я видел файл журнала, захваченный с вредоносного веб-сайта, который содержал 400 МБ случайных транзакций GET / POST, захваченных из пользовательских сеансов. Вы можете себе представить, что веб-сайты, использующие только HTTPS, будут отображаться с паролями в виде открытого текста в журнале, но веб-сайты с очень простой обфускацией (ROT13) также будут отображаться с паролями, которые не используются немедленно.
Если вы подключены к серверу https, поток данных между сервером и браузером должен быть зашифрован. Перед отправкой и после получения данные представляют собой простой текст. Статья в Википедии
Отказ от ответственности: я ни в коем случае не эксперт по безопасности - и я пишу с надеждой, что другие будут критиковать мою позицию как чрезмерно осторожную или несостоятельную, и я извлечу из нее уроки. С учетом сказанного, я просто хочу подчеркнуть, что хеширование, когда оно покидает ваш клиент, не означает, что вам не нужно хешировать на бэкэнде, прежде чем помещать его в базу данных.
Сделайте оба
Сделайте и то, и другое, потому что:
Хеширование во время поездки помогает скрыть уязвимости транспорта: если SSL-соединение скомпрометировано, они все равно не смогут увидеть необработанный пароль. Это не имеет значения с точки зрения возможности выдавать себя за авторизованных пользователей, но это защитит ваших пользователей от того, чтобы их пароли считывались вместе с их электронной почтой. Большинство людей не следуют передовой практике и используют один и тот же пароль для многих своих учетных записей, поэтому это может быть серьезной уязвимостью для ваших посетителей.
Если кто-то каким-то образом смог прочитать пароли из базы данных (это действительно происходит, подумайте о SQL-инъекции), он все равно не сможет выполнять привилегированные действия, олицетворяющие пользователей, через мой API. Это из-за асимметрии хэша; даже если они знают хэш, хранящийся в вашей БД, они не будут знать исходный ключ, использованный для его создания, и то, что ваше промежуточное программное обеспечение auth использует для аутентификации. Вот почему вы всегда должны солить хеш-хранилище.
Конечно, они могли бы нанести много другого вреда, если бы у них была свобода чтения из вашей базы данных.
Я просто хочу подчеркнуть здесь, что если вы решите хешировать ключ перед уходом от своих клиентов, этого недостаточно - бэкэнд-хеширование, я думаю, гораздо важнее, и вот почему: если кто-то перехватывает трафик с вашего client, то они увидят содержимое password
поля. Неважно, хеш это или простой текст - они могут скопировать его дословно, чтобы выдать себя за авторизованного клиента. (Если вы не выполните шаги, описанные в @ user3299591, и я рекомендую вам это сделать). С другой стороны, хеширование столбца БД является необходимостью и совсем не сложно реализовать.
Разве SSL / TLS не заменяет одноразовый номер? Я не вижу в этом дополнительной ценности, поскольку SSL / TLS также защищает от атак с повторением.
На самом деле было бы менее безопасно хешировать пароль и отправлять его по незашифрованному каналу. Вы выставите свой алгоритм хеширования на клиенте. Хакеры могут просто обнюхать хэш пароля, а затем использовать его для взлома позже.
Используя HTTPS, вы предотвращаете получение хакером пароля из одного источника, поскольку HTTPS использует два канала, оба зашифрованные.
Есть ли преимущество и действительно ли оно более (или менее) безопасно, зависит от реализации. Возможно, есть некоторое преимущество, но если вы реализуете его плохо, вы определенно сможете создать решение, которое будет менее безопасным, чем передача даже простого текстового пароля.
На это можно взглянуть с точки зрения двух типов атак: одна с доступом к сетевому трафику, а другая с доступом к базе данных.
Если ваш злоумышленник может перехватить текстовую версию сетевого трафика, тогда просмотр хеш-кода пароля более безопасен, чем просмотр пароля в открытом виде. Хотя злоумышленник по-прежнему может войти на ваш сервер, используя этот хэш, для определения пароля, который может быть полезен в других системах, потребуется взломать этот хеш (иногда предварительно вычисленный) методом перебора. Люди должны использовать разные пароли в разных системах, но часто этого не делают.
Если злоумышленник получил доступ к базе данных, возможно, через копию резервной копии, тогда вам нужно убедиться, что он не может войти в систему, имея только эти знания. Если, например, вы сохранили хэш с именем для входа как hash(login_name+password)
, и вы передали тот же хеш от клиента для прямого сравнения, тогда злоумышленник может выбрать пользователя случайным образом, отправить хэш, прочитанный из базы данных и войти в систему как этот пользователь, не зная пароля, увеличивает масштаб нарушения. В этом случае отправка пароля в виде открытого текста была бы более безопасной, поскольку злоумышленнику необходимо было бы знать открытый текст для входа в систему, даже имея копию базы данных. Вот где реализация является ключевой. Независимо от того, отправляете ли вы пароль в виде открытого текста или хеш-код этого пароля на стороне клиента, вы должны хешировать это значение на стороне сервера и сравнивать этот хэш с хешем, хранящимся в записи пользователя.
Концепции, о которых следует помнить: