Стоит ли хешировать пароли на стороне клиента? - PullRequest
114 голосов
/ 15 сентября 2010

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

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

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

Ответы [ 10 ]

102 голосов
/ 15 сентября 2010

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

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

На сервере:

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

На клиенте:

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

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

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

57 голосов
/ 10 мая 2014

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

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

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

Без TLS любое шифрование становится бессмысленным, потому что, если я сижу рядом с вами в кафе, я могу заставить ваш ноутбук / смартфон думать, что я сервер, а вы MiTM (Man in the Middle). При использовании TLS ваш ноутбук / смартфон будет кричать «Ненадежное соединение», потому что у меня нет сертификата, подписанного центром сертификации, который соответствует вашему сайту. (Шифрование против аутентификации).

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

Однако, если вы действительно не хотите покупать сертификат, все равно НЕОБХОДИМО реализовать хеширование JavaScript на стороне клиента (и для этого использовать стандартную библиотеку (SJCL), НИКОГДА НЕ РЕАЛИЗОВАТЬ КРИПТО САМОГО ).

Почему? Повторное использование пароля! Я могу украсть ваш сессионный 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

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

21 голосов
/ 15 сентября 2010

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

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

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


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

9 голосов
/ 17 января 2014

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

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

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

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

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

3 голосов
/ 30 июня 2011

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

посмотрите на ссылку Шифрование пароля на стороне клиента

2 голосов
/ 30 августа 2018

Обратите внимание, что обеспечение безопасности паролей от третьих сторон - это еще не все.

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

Следовательно, хэширование /шифрование на стороне клиента имеет смысл.

1 голос
/ 04 мая 2018

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

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

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

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

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

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

1 голос
/ 20 октября 2013

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

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

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

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

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

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

1 голос
/ 09 июня 2013

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

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

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

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

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

0 голосов
/ 04 ноября 2017

Примите во внимание следующее: -

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

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

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

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

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

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

...