Стоит ли хешировать пароли на стороне клиента

Когда я хочу поставить систему входа в систему, я всегда сравниваю MD5 данного пароля со своим значением в таблице пользователей на стороне сервера.

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

Итак, мой вопрос: хорошо ли хешировать пароль на стороне клиента? Это лучше, чем хэширование на стороне сервера?

Ответ 1

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

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

На сервере:

  • создать несколько бит случайных
  • отправьте эти биты (в открытом тексте) клиенту

На клиенте:

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

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

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

Ответ 2

Прежде всего, это означает, что НЕ повышает безопасность вашего приложения (при условии, что это веб-приложение).

Использовать SSL (или фактически TLS, который обычно называется SSL), его не очень дорого (измерьте время, которое вы используете, чтобы найти пути вокруг него и умножить его на минимальную заработную плату, покупка сертификата выигрывает почти всегда).

Почему это просто. TLS решает проблему (при использовании с купленными сертификатами, а не самостоятельно), что является довольно большим в криптографии: откуда я знаю сервер, с которым я разговариваю, является сервером, на который, я думаю, разговариваю? Сертификаты TLS - это способ сказать: "Я, авторитет сертификата, которому доверяет ваш браузер, подтверждает, что на веб-сайте [url] этот открытый ключ с соответствующим закрытым ключом, который (закрытый ключ) знает только сервер, выглядит Я подписал мою подпись по всему документу, если кто-нибудь ее изменил, вы можете увидеть".

Без TLS любое шифрование становится бессмысленным, потому что, если я буду сидеть рядом с вами в кофейне, я могу заставить ваш ноутбук/смартфон подумать, что я сервер и MiTM (Man in The Middle). С помощью TLS ваш ноутбук/смартфон будет кричать "UNTRUSTED CONNECTION", потому что у меня нет сертификата, подписанного сертификатом, который соответствует вашему сайту. (Шифрование против аутентификации).

Отказ от ответственности: пользователи, как правило, щелкают по этим предупреждениям: "Неверное соединение? Что? Я просто хочу, чтобы мои фотографии котят!" Добавить исключение Нажмите "Подтвердить" Нажмите "YAY! Kittens!"

Однако, если вы действительно не хотите покупать сертификат, еще DO реализовать хэширование javascript на стороне клиента (и использовать для этого библиотеку standford (SJCL) НИКОГДА НЕ РЕАЛИЗАЦИЯ CRYPTO YOURSELF).

Почему? Повторное использование пароля! Я могу украсть ваш cookie сеанса (который позволяет мне притворяться вашим сервером, что я являюсь вам) без HTTPS легко (см. Firesheep). Однако, если вы добавите javascript на свою страницу входа в систему, которая перед отправкой хеширует ваш пароль (используйте SHA256 или даже лучше, используйте SHA256, отправьте им открытый ключ, который вы создали, а затем зашифруете с помощью этого пароля, вы не можете использовать соль с этим), а затем отправляет хешированный/зашифрованный пароль на сервер. ЗАПРЕЩАЕТ хэш на вашем сервере с солью и сравните его с тем, что хранится в вашей базе данных (сохраните пароль следующим образом:

(SHA256(SHA256(password)+salt))

(сохранить соль как открытый текст в базе данных)). И отправьте свой пароль следующим образом:

RSA_With_Public_Key(SHA256(password))

и проверьте свой пароль следующим образом:

if SHA256(RSA_With_Private_Key(SHA256(sent_password))+salt_for_username) == stored_pass: login = ok

Поскольку IF кто-то обнюхивает вашего клиента, они смогут войти в систему как ваш клиент (захват сеанса), но они будут НИКОГДА видеть пароль открытого текста (если только они измените свой javascript, однако злоумышленник starbucks, вероятно, не знает, как/быть заинтересованным в этом.) Таким образом, они получат доступ к вашему webapp, но не к их электронной почте/facebook/и т.д. (для которых ваши пользователи, скорее всего, будут использовать один и тот же пароль). (Адрес электронной почты будет либо иметь имя пользователя, либо будет отображаться в их профиле/настройках на вашем веб-сервере).

Ответ 3

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

Это немного лучше, поскольку он не позволяет злоумышленнику узнать, что такое пароль, но поскольку они все еще могут войти (или, возможно, восстановить оригинальный пароль), что не так полезно.

В целом, если вас беспокоит безопасность ваших паролей пользователей и данных (и вы должны быть!), вы захотите использовать безопасный SSL-сервер. Если это не касается вас по какой-либо причине, вы можете не беспокоиться о хэшировании; это просто безопасность через безвестность.


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

Ответ 4

На самом деле я не согласен с тем, что хеширование на стороне клиента более безопасно в этом случае. Я думаю, что это менее безопасно.

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

Если ваш механизм проверки подлинности отправляет хэш пароля, то в этом сценарии нарушения безопасности злоумышленнику не нужно знать настоящий пароль - они просто отправляют хэш, который у них есть, и hey presto, у них есть доступ к определенному учетной записи пользователя, а также всей вашей системы. Это полностью разрушает точку хранения хешированного пароля в первую очередь!

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

Кстати, такой вопрос, вероятно, получит больше экспертных ответов в Security StackExchange.

Ответ 6

В последнее время я много работаю над этим, у IRL есть две проблемы с хэш-символом на стороне клиента/симметричным шифрованием, которые действительно убивают идею: 1. Вы должны вернуть соль обратно на сервер. И чтобы зашифровать его на стороне клиента, вам понадобится пароль... который побеждает цель. 2. Вы публикуете свою реализацию хеширования (а не ОГРОМНУЮ сделку, так как большинство сайтов используют один или три хэширующих альгоса), что облегчает атаку (просто нужно попробовать одну, а не n).

В конце концов я пошел на асимметричное шифрование на клиенте, используя OpenPGP.js или подобное... Это зависит от импортированного или клиентского сгенерированного ключа на клиенте, а сервер отправляет ему открытый ключ. Только клиентский открытый ключ может быть отправлен обратно на сервер. Это защищает от MIM-атак и настолько же безопасно, как и устройство (я в настоящее время храню закрытый ключ клиента по умолчанию в localStore, это демо).

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

Основой этого было предоставление людям возможности безопасного общения, где HTTPS был ограничен (например, Иран/Северная Корея), а также просто забавный эксперимент.

Я FAR от первого, чтобы подумать об этом, http://www.mailvelope.com/ использует это

Ответ 7

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

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

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

Данные пользователя также зашифровываются на стороне браузера.

Ах, поэтому атака среднего человека получит зашифрованные данные, но не сможет расшифровать ее без фактического пароля, используемого для входа. (пароль пользователя, хранящийся в DOM в браузере при входе в систему). Таким образом, реальный пользователь увидит расшифрованное содержимое, но средний человек не смог. Это также означает, что любое NSA или другое агентство не смогут запросить у вас/поставщика/хостинг-провайдера возможность расшифровать эти данные, поскольку для них также было бы невозможно сделать это.

Некоторые небольшие примеры обоих этих методов находятся в моем блоге http://glynrob.com/javascript/client-side-hashing-and-encryption/

Ответ 8

Недавно GitHub и Twitter анонсировали пароли, хранящиеся во внутренних журналах. У меня это произошло случайно в отчетах об ошибках и других журналах, которые нашли свой путь в splunk и т.д. Для twitter, если в Trump-пароле есть журнал, это может быть большой проблемой для "видеть" администратора, для других сайтов, вероятно, не так большая часть сделки, поскольку администраторы не имели бы для этого много пользы. Независимо от того, как админы нам не нравятся, мы видим пароли.

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

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

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

Объединитесь с файлом cookie, который не будет отправлен обратно на сервер, и вы можете что-то сказать. По первому запросу отправьте cookie клиенту с ключом, а затем убедитесь, что cookie не возвращается к службе входа, так что мало шансов на регистрацию. Храните ключ в хранилище сеансов, а затем удаляйте его сразу после входа в систему или с истечением срока действия сеанса... для этого вам нужно состояние для парней JWT, но, возможно, просто используйте для него службу nosql.

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

Ответ 10

Рассмотрим следующее: -

Клиент отправляет запрос на сервер "У меня есть пароль для проверки".

Сервер отправляет клиенту одноразовую случайную строку. R $

Клиент вводит пароль пользователя в этой строке (на основе любых (переменных) правил, которые вы хотите применить).

Клиент отправляет строку на сервер, и если пароль ОК, сервер регистрирует пользователя.

Если сервер получит другой запрос на вход, используя R $, пользователь выйдет из системы, и учетная запись будет заморожена в ожидании расследования.

Очевидно, что все другие (обычные) меры предосторожности будут приняты.

Ответ 11

Можно рассмотреть сайты, такие как amazon.com и linkedin.com. Эти сайты не имеют хеша на стороне клиента. (По состоянию на апрель 2018 года).