outcoldman
outcoldman Denis Gladkikh

Хеш-функции и безопасная аутентификация

SSL, Cryptography, Криптография, Хеш-Функция, SHA1, and MD5

В продолжение этой [2] статьи – сегодня хочу рассказать и поговорить про хеш-функции, с этого, можно сказать, начинается криптография. Итак, известно, что хеш-функция (называют так же операция хеширования) – это некоторое преобразование строки любой длины в строку данных фиксированной длины. На практике, чаще всего, встречаются два алгоритма хеширования – MD5 и SHA1, вероятность коллизий (получение одинаковых хеш-значений с разных сообщений) для MD-5, например, уже найдена. Стандартный пример использования: скачивание больших файлов – чтобы проверить, что архив скачался удачно – рядом со ссылкой скачивания кладут, например, его хеш-значение MD5, и скачавший может запросто проверить что архив не поврежден.

Возможность использования хеш-функций и их реализация практически есть везде, в .NET – это MD5CryptoServiceProvider (для вычисления MD5), SHA1CryptoServiceProvider (для SHA1), в T-SQL – это HashBytes. И более того – алгоритм достаточно хорошо описан, и реализовать его очень просто, студенты ВУЗов часто получают в качестве лабораторной работы – реализацию какой-нибудь хеш-функции.

Следует вопрос, а когда же нам их применять? Вообще? лучше смотреть на данные, хранящиеся от пользователя в следующем ключе: если они вам не нужны (по честному не нужны), а нужно только знать, что в будущем человек ввел такие же данные, то имеет смысл хранить не сами данные, а хеш-значение. Такими данными являются, например, пароли и номера кредиток. Недавно я стал свидетелем того, что в программе хранились пароли в незахешированном виде – постарался это исправить как можно быстрее, хотя даже сами пользователи просили меня не делать этого, а то часто забывают пароли и админа просят посмотреть их в БД (разве так можно?). Вообще, на проблемы с безопасностью я смотрел бы так: ошибка в программе чаще всего обнаруживается быстро и ее легко исправить, ошибка в безопасности – может быть не обнаружена вовсе, а если будет обнаружена, то скорее всего принесет ущерб, исправить последствия которого будет невозможно. Так, например, если вы создали очень интересный ресурс, на котором посещаемость увеличилась до 1000 людей в день, и всего у вас зарегистрировано 50 000 человек – вы может уже купаетесь в деньгах от контекстной рекламы (не знаю как это все происходит), как тут обнаруживается брешь на сайте, позволяющая выполнить sql-инъекцию с получением списка пользователей и их паролями. А вы как-то и не задумывались хешировать пароли, а зачем? Будут ли потом доверять вам посетители? Репутацию ваш сайт может потерять. Вроде мелочь, а это стандартные вещи, которые иногда игнорируют.

Итак дальше, как часто при заходе на сайт мы задумываемся: при аутентификации мы отправляем пароль по защищенному каналу или нет? Можете прямо сейчас перечислить 10 сайтов на память, которые так делают? Большая брешь во множествах сайтах находится именно в аутентификации – мы заходим на сайт по http (не защищенному соединению), нас просят ввести логин и пароль – мы вводим и нажимаем Login, в этом время наш трафик может кто-то просматривать и записывать себе в базу данных логины и пароли на будущее. Можете сами попробовать воспользовавшись программой Fiddler2. Что мы можем с этим поделать? Вообще в статье [1] приводится самый простой способ решения проблемы – устанавливаем сертификат на сервер, и защищаем канал. Известно, что SSL – влияет на производительность, но на простом сайте он нам нужен только один раз – при заходе на страницу аутентификации, а дальше записываем информацию о залогиненном пользователе в cookie и пароль больше передаваться не будет (у cookie есть свои возможности защиты, о чем так же написано в [1], чтобы сделать невозможным подмену пользователя). Сертификат для своего сайта опять же лучше покупать у какого-нибудь доверенного источника, сертификат УЦ которого уже есть по-умолчанию в Windows системах (об этом уже обсуждали в [2]).

Если покупать сертификат не хочется или нет возможности – можем так же хешировать пароль прямо на стороне клиента [3], и отправлять его уже в захешированном виде. Конечно же не нужно забывать о пользователях, у которых не включен JavaScript – для них мы можем отображать div с надписью “Так как JavaScript у вас не включен, то ваш пароль буден отправлен на сервер в незахешированном виде.” (ну или что-то вроде того), скрывать который будем при помощи JavaScript (соответственно, если он не включен то и не скроется). Вроде реализация очень простая, почему, странно, контрол ASP.NET Login этого не реализует? Если решите реализовать такое, то обязательно прочтите [3], а именно тут.

Понимаю, что многое тут кажется немного параноидальным, но все относительно. Но все же рекомендую к прочтению [1], если вы с этим мало знакомы.

Литература

  1. Разработка и развертывание защищенных Web-приложений для ASP.NET 2.0 и IIS 6.0
  2. Криптография. Сертификаты. Знакомство с SSL.
  3. JavaScript MD5

Have feedback or questions? Looking for consultation?

My expertise: MongoDB, ElasticSearch, Splunk, and other databases. Docker, Kubernetes. Logging, Metrics. Performance, memory leaks.

Send me an email to public@denis.gladkikh.email.

The content on this site represents my own personal opinions and thoughts at the time of posting.

Content licensed under the Creative Commons CC BY 4.0.