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

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

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

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

12 ответов


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

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

на сервере:

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

на клиенте:

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

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

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


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

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

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

без TLS любое шифрование становится бессмысленным, потому что если Я сижу рядом с вами в кафе, я могу заставить ваш ноутбук/смартфон думать, что я сервер и MiTM (человек в середине) вас. С TLS ваш ноутбук / смартфон будет кричать "ненадежное соединение", потому что у меня нет сертификата, подписанного центром сертификации, который соответствует вашему сайту. (Шифрование и аутентификация).

отказ от ответственности: пользователи, как правило, нажимают прямо через эти предупреждения: "ненадежное соединение? Что? Я просто хочу свои фотографии котят! Добавить Исключение клик подтвердить клик УРА! Котята!"

однако, если вы действительно не хотите покупать сертификат, все же реализуйте хеширование javascript на стороне клиента (и используйте для этого библиотеку standford (SJCL),НИКОГДА НЕ РЕАЛИЗОВЫВАЙТЕ CRYPTO САМОСТОЯТЕЛЬНО).

почему? Повторное использование пароля! Я могу украсть ваш файл cookie сеанса (который позволяет мне притворяться на вашем сервере, что я-это вы) без HTTPS легко (см. firesheep). Однако, если вы добавить JavaScript к вашему логину страницу, на которой перед отправкой, хэширует пароль (использовать SHA256, или даже лучше, использовать SHA256, отправить открытый ключ генерируется, а затем зашифровать хэшированный пароль с этого, нельзя использовать соль в этом), а затем отправляет хэш/пароль к серверу. REHASH хэш на вашем сервере с солью и сравните это с тем, что хранится в вашей базе данных (сохраните пароль следующим образом:

(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, вероятно, не будет знать, как/быть заинтересованным в этом.) Таким образом, они получат доступ к вашему webapp, но не к их электронной почте / facebook / etc. (за что ваши пользователи будут использовать тот же пароль). (Адрес электронной почты будет либо их loginname или будет найден в их профиле / настройках на вашем webapp).


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

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

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


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


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

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

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

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

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


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

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


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

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

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

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

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


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

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

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

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

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

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


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

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

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

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

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

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


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

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

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


рассматривайте это:-

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

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

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

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

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

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


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


можно использовать любые сторонние библиотеки, такие как

jCryption

шифрование на стороне клиента с помощью jCryption