Что такое хэш пароля

Немного о хэшах и безопасном хранении паролей

Upd. Если вы знаете, что такое BCrypt, можете дальше не читать. Если вы используете PHP 5.5+ то можете прочитать эту статью. Ниже же я изобрел свой велосипед, рабочий, но с двумя рулями, задний запасной. Молод был, горяч.

Привет, хабр! Сегодня, в процессе разработки системы аутентификации для своего проекта передо мной встал выбор — в каком виде хранить пароли пользователей в базе данных? В голову приходит множество вариантов. Самые очевидные:

Коллизия хеш-функций

Коллизия хеш-функции возникает, когда она выдает одинаковый результат на разные входные данные. Конечно же, вероятность этого достаточно мала, и зависит от длины хэша. Однако устаревшая (но до сих пор иногда используемая) функция crc32() возвращает в качестве хэша 32-битное целое число. Т.е., чтобы подобрать пароль к такому хэшу, по теории вероятности нужно получить 2^32 = 4 294 967 296 различных хэшей. Даже на моем бесплатном хостинге crc32 работает со скоростью порядка 350 000 раз в секунду — посчитайте сами сколько нужно секунд, чтобы взломать такой хэш 😉

Конечно же это не относится к md5() (128-битный хеш) и тем более sha1() (160-битный хеш). Использовать их коллизию практически невозможно, хотя есть одна статейка.

Радужные таблицы

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

Радужные таблицы. Часть 2

Статическая соль и тому подобные конструкции могут служить достаточно хорошо… пока структура этих конструкций и соль хранятся в тайне. Если же злоумышленник вызнает секрет хэширования — он с легкостью сможет модифицировать под него свою «радужную таблицу». А т.к. мы не можем абсолютно полагаться на систему защиты своего сервера, нужно искать другой вариант. Одним из решений может быть генерация уникальной соли для каждого юзера, что-то вроде:

Еще лучше генерировать совсем случайную соль, например так:

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

Скорость хэширования

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

Современные ПК с мощными GPU, могут рассчитывать миллионы хэшей в секунду и больше. А это позволяет ломать пароли простым подбором, с помощью брутфорса-атак. Считаете что пароль в 8 символов достаточно безопасен? Если в пароле используются символы в нижнем и верхнем регистрах и цифры, то общее количество возможных символов составит 62 (26+26+10). Для пароля длиной в 8 символов, существует 62^8 различных комбинаций (порядка 218 триллионов). Со скоростью в 1 миллиард хэшей в секунду (достаточно маленькая для брутфорс-атаки), пароль будет сломан примерно за 60 часов. А для наиболее распространенной длины пароля в 6 символов, длительность расшифровки составит меньше двух минут.

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

Используя ее, вместо 60 часов, хакер будет ломать 8-символьный пароль около 7 лет. Более удобным вариантом замедления, является использование алгоритма Blowfish, реализованного в PHP через crypt(). Проверить доступность этого алгоритма можно с помощью if (CRYPT_BLOWFISH == 1) echo ‘it works!’; В PHP 5.3 Blowfish уже включен.

$2a — это указание на то, что будет использоваться алгоритм Blowfish
$10 — это сила замедления функции. В данном случае равна 2^10. Может принимать значения от 04 до 31

Используем ее на конкретном примере:

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

Источник

Как надо хешировать пароли и как не надо

Что такое хэш пароля. image loader. Что такое хэш пароля фото. Что такое хэш пароля-image loader. картинка Что такое хэш пароля. картинка image loader. Upd. Если вы знаете, что такое BCrypt, можете дальше не читать. Если вы используете PHP 5.5+ то можете прочитать эту статью. Ниже же я изобрел свой велосипед, рабочий, но с двумя рулями, задний запасной. Молод был, горяч.

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

Постараюсь очень лаконично и быстро обрисовать ситуацию с хэшами.

Сразу определю какую задачу применения хешей буду рассматривать — аутентификация пользователей. Не токены восстановления паролей, не аутентификация запросов, не что-то еще. Это также не статья про защиту канала передачи данных, так что комментарии по challenge-response и SSL неуместны!

Матчасть (короткая)

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

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

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

Для выполнения первого требования нужно использовать стойкие в настоящее время (а не в 90х годах!) хеш-функции.
Для выполнения второго — к паролю перед хешированием добавляется случайная строка (соль). Таким образом, у двух пользователей с паролем «123456» будут разные соли «соль1» и «соль2», а соответственно и хеш-функции от «123456соль1» и «123456соль2» в базе тоже будут разные.

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

Используйте локальный параметр!

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

Для того чтобы еще усложнить жизнь атакующему, Solar Designer www.openwall.com/presentations/YaC2012-Password-Hashing-At-Scale/mgp00005.html предлагает ввести еще одну штуку, под названием локальный параметр.

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

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

Единственный раз мы (ONsec) ломали хеши с локальным параметром, выработав при этом тактику атаки на сам локальный параметр (регистрируемся в приложении, затем ищем в базе свой хеш, соль (свой пароль мы и так знаем) и перебираем ЛП). И тщетно. На длинах 16+ байт для современных функций хеширования — это очень дорого по железу. В итоге проще оказалось скомпрометировать систему аутентификации (проставить себе role=admin в базе через UPDATE 😉 )

Защищайте свои хранилища надежно и грамотно!

Заключение

Буду реалистом — естественно, никто не станет переписывать свои проекты ради «каких-то» хешей. Но новые проекты можно писать на scrypt/bcrypt. А также — внедряйте локальный параметр даже на слабых MD5 — он правда помогает, проверено 🙂

При переходе на другой тип хеширования, помимо трудозатрат, часто встает вопрос производительности. Действительно, более стойкие алгоритмы потребляют больше ресурсов. Тестируйтесь перед внедрением для своих нагрузок по скорости аутентификации пользователей в секунду (для большинства крупных проектов переход на scrypt оказался безболезненным). Выбор конкретного идеального типа хеша в конкретной ситуации может сильно разнится. Так, например, ДБО все чаще выбирают железные решения для генерации хешей с заданной скоростью.

Источник

Чудеса хеширования

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

Что такое хэш пароля. don. Что такое хэш пароля фото. Что такое хэш пароля-don. картинка Что такое хэш пароля. картинка don. Upd. Если вы знаете, что такое BCrypt, можете дальше не читать. Если вы используете PHP 5.5+ то можете прочитать эту статью. Ниже же я изобрел свой велосипед, рабочий, но с двумя рулями, задний запасной. Молод был, горяч.

Что такое хэш пароля. hash. Что такое хэш пароля фото. Что такое хэш пароля-hash. картинка Что такое хэш пароля. картинка hash. Upd. Если вы знаете, что такое BCrypt, можете дальше не читать. Если вы используете PHP 5.5+ то можете прочитать эту статью. Ниже же я изобрел свой велосипед, рабочий, но с двумя рулями, задний запасной. Молод был, горяч.

Криптографические хеш-функции — незаменимый и повсеместно распространенный инструмент, используемый для выполнения целого ряда задач, включая аутентификацию, проверку целостности данных, защиту файлов и даже обнаружение зловредного ПО. Существует масса алгоритмов хеширования, отличающихся криптостойкостью, сложностью, разрядностью и другими свойствами. Считается, что идея хеширования принадлежит сотруднику IBM, появилась около 50 лет назад и с тех пор не претерпела принципиальных изменений. Зато в наши дни хеширование обрело массу новых свойств и используется в очень многих областях информационных технологий.

Что такое хеш?

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

Как работает хеш?

Например, мое имя — Brian — после преобразования хеш-функцией SHA-1 (одной из самых распространенных наряду с MD5 и SHA-2) при помощи онлайн-генератора будет выглядеть так: 75c450c3f963befb912ee79f0b63e563652780f0. Как вам скажет, наверное, любой другой Брайан, данное имя нередко пишут с ошибкой, что в итоге превращает его в слово brain (мозг). Это настолько частая опечатка, что однажды я даже получил настоящие водительские права, на которых вместо моего имени красовалось Brain Donohue. Впрочем, это уже другая история. Так вот, если снова воспользоваться алгоритмом SHA-1, то слово Brain трансформируется в строку 97fb724268c2de1e6432d3816239463a6aaf8450. Как видите, результаты значительно отличаются друг от друга, даже несмотря на то, что разница между моим именем и названием органа центральной нервной системы заключается лишь в последовательности написания двух гласных. Более того, если я преобразую тем же алгоритмом собственное имя, но написанное уже со строчной буквы, то результат все равно не будет иметь ничего общего с двумя предыдущими: 760e7dab2836853c63805033e514668301fa9c47.

Впрочем, кое-что общее у них все же есть: каждая строка имеет длину ровно 40 символов. Казалось бы, ничего удивительного, ведь все введенные мною слова также имели одинаковую длину — 5 букв. Однако если вы захешируете весь предыдущий абзац целиком, то все равно получите последовательность, состоящую ровно из 40 символов: c5e7346089419bb4ab47aaa61ef3755d122826e2. То есть 1128 символов, включая пробелы, были ужаты до строки той же длины, что и пятибуквенное слово. То же самое произойдет даже с полным собранием сочинений Уильяма Шекспира: на выходе вы получите строку из 40 букв и цифр. При всем этом не может существовать двух разных массивов данных, которые преобразовывались бы в одинаковый хеш.

Вот как это выглядит, если изобразить все вышесказанное в виде схемы:

Что такое хэш пароля. Cryptographic Hashing Explained Rus. Что такое хэш пароля фото. Что такое хэш пароля-Cryptographic Hashing Explained Rus. картинка Что такое хэш пароля. картинка Cryptographic Hashing Explained Rus. Upd. Если вы знаете, что такое BCrypt, можете дальше не читать. Если вы используете PHP 5.5+ то можете прочитать эту статью. Ниже же я изобрел свой велосипед, рабочий, но с двумя рулями, задний запасной. Молод был, горяч.

Для чего используется хеш?

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

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

Вы даже можете провести простой эксперимент: попробуйте при помощи специального сайта произвести преобразование какого-нибудь простого пароля вроде «123456» или «password» из их хеш-значений (созданных алгоритмом MD5) обратно в текст. Вероятность того, что в базе хешей найдутся данные о введенных вами простых паролях, очень высока. В моем случае хеши слов «brain» (8b373710bcf876edd91f281e50ed58ab) и «Brian» (4d236810821e8e83a025f2a83ea31820) успешно распознались, а вот хеш предыдущего абзаца — нет. Отличный пример, как раз для тех, кто все еще использует простые пароли.

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

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

Где еще можно использовать хеш-функции помимо систем хранения паролей и защиты медиафайлов? На самом деле задач, где используется хеширование, гораздо больше, чем я знаю и тем более могу описать в одной статье. Однако есть одна особенная область применения хешей, особо близкая нам как сотрудникам «Лаборатории Касперского»: хеширование широко используется для детектирования зловредных программ защитным ПО, в том числе и тем, что выпускается нашей компанией.

Как при помощи хеша ловить вирусы?

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

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

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

Источник

Риски и проблемы хеширования паролей

Безопасность всегда была неоднозначной темой, провоцирующей многочисленные горячие споры. И всё благодаря обилию самых разных точек зрения и «идеальных решений», которые устраивают одних и совершенно не подходят другим. Я считаю, что взлом системы безопасности приложения всего лишь вопрос времени. Из-за быстрого роста вычислительных мощностей и увеличения сложности безопасные сегодня приложения перестанут завтра быть таковыми.

Недостатки простого хэширования

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

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

Почему небезопасны хэши с применением соли

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

В общем виде функцию с использованием соли можно представить так:

f(password, salt) = hash(password + salt)

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

if (hash([введённый пароль] + [соль]) == [хэш]) тогда пользователь аутентифицирован

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

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

Момент случайности

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

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

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

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

Что такое хэш пароля. image loader. Что такое хэш пароля фото. Что такое хэш пароля-image loader. картинка Что такое хэш пароля. картинка image loader. Upd. Если вы знаете, что такое BCrypt, можете дальше не читать. Если вы используете PHP 5.5+ то можете прочитать эту статью. Ниже же я изобрел свой велосипед, рабочий, но с двумя рулями, задний запасной. Молод был, горяч.

А теперь сравните с данными, сгенерированными полноценным генератором случайных чисел:

Что такое хэш пароля. image loader. Что такое хэш пароля фото. Что такое хэш пароля-image loader. картинка Что такое хэш пароля. картинка image loader. Upd. Если вы знаете, что такое BCrypt, можете дальше не читать. Если вы используете PHP 5.5+ то можете прочитать эту статью. Ниже же я изобрел свой велосипед, рабочий, но с двумя рулями, задний запасной. Молод был, горяч.

К сожалению, ни rand(), ни mt_rand() нельзя считать подходящими инструментами для обеспечения высокого уровня безопасности.

Если вам нужно получить случайные данные, воспользуйтесь функцией openssl_random_pseudo_bytes(), которая доступна начиная с версии 5.3.0. У неё даже есть флаг crypto_strong, который сообщит о достаточном уровне безопасности.

Растяжение пароля

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

Что такое хэш пароля. fca4f0e50e8d468a8b37667f8d272cc2. Что такое хэш пароля фото. Что такое хэш пароля-fca4f0e50e8d468a8b37667f8d272cc2. картинка Что такое хэш пароля. картинка fca4f0e50e8d468a8b37667f8d272cc2. Upd. Если вы знаете, что такое BCrypt, можете дальше не читать. Если вы используете PHP 5.5+ то можете прочитать эту статью. Ниже же я изобрел свой велосипед, рабочий, но с двумя рулями, задний запасной. Молод был, горяч.

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

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

Есть и более затратные по времени и памяти алгоритмы, например bcrypt (о нём мы поговорим ниже) или scrypt:

На данный момент в PHP не реализована поддержка алгоритма scrypt, но можно воспользоваться реализацией от Domblack.

Применение технологий шифрования

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

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

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

Некоторое время назад у Adobe была мощная утечка пользовательской БД из-за неправильно реализованного шифрования. Давайте разберём, что у них произошло.

Что такое хэш пароля. image loader. Что такое хэш пароля фото. Что такое хэш пароля-image loader. картинка Что такое хэш пароля. картинка image loader. Upd. Если вы знаете, что такое BCrypt, можете дальше не читать. Если вы используете PHP 5.5+ то можете прочитать эту статью. Ниже же я изобрел свой велосипед, рабочий, но с двумя рулями, задний запасной. Молод был, горяч.

Предположим, что в таблице хранятся следующие данные в виде обычного текста:

Что такое хэш пароля. image loader. Что такое хэш пароля фото. Что такое хэш пароля-image loader. картинка Что такое хэш пароля. картинка image loader. Upd. Если вы знаете, что такое BCrypt, можете дальше не читать. Если вы используете PHP 5.5+ то можете прочитать эту статью. Ниже же я изобрел свой велосипед, рабочий, но с двумя рулями, задний запасной. Молод был, горяч.

Что такое хэш пароля. image loader. Что такое хэш пароля фото. Что такое хэш пароля-image loader. картинка Что такое хэш пароля. картинка image loader. Upd. Если вы знаете, что такое BCrypt, можете дальше не читать. Если вы используете PHP 5.5+ то можете прочитать эту статью. Ниже же я изобрел свой велосипед, рабочий, но с двумя рулями, задний запасной. Молод был, горяч.

Мы не знаем, какой применялся криптоключ. Но если проанализировать данные, то можно заметить, что в строках 2 и 7 используется один и тот же пароль, так же как и в строках 3 и 6.

Пришло время обратиться к подсказке пароля. В строке 6 это «I’m one!», что совершенно неинформативно. Зато благодаря строке 3 мы можем предположить, что пароль — queen. Строки 2 и 7 по отдельности не позволяют вычислить пароль, но если проанализировать их вместе, то можно предположить, что это halloween.

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

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

Простейший вариант «настройки» — так называемый первичный ключ, уникальный для каждой записи в таблице. Не рекомендуется пользоваться им в жизни, здесь он показан лишь для примера:

f(key, primaryKey) = key + primaryKey

Здесь ключ и первичный ключ просто сцепляются вместе. Но для обеспечения безопасности следует применить к ним алгоритм хэширования или функцию формирования ключа (key derivation function). Также вместо первичного ключа можно для каждой записи использовать одноразовый ключ (аналог соли).

Если мы применим к нашей таблице настраиваемое шифрование, то она будет выглядеть так:

Что такое хэш пароля. image loader. Что такое хэш пароля фото. Что такое хэш пароля-image loader. картинка Что такое хэш пароля. картинка image loader. Upd. Если вы знаете, что такое BCrypt, можете дальше не читать. Если вы используете PHP 5.5+ то можете прочитать эту статью. Ниже же я изобрел свой велосипед, рабочий, но с двумя рулями, задний запасной. Молод был, горяч.

Конечно, нужно будет ещё что-то сделать с подсказками паролей, но всё-таки уже получилось хоть что-то адекватное.

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

PHP 5.5

Сегодня оптимальным способом хэширования паролей считается использование bcrypt. Но многие разработчики всё ещё предпочитают старые и более слабые алгоритмы вроде MD5 и SHA-1. А некоторые при хэшировании даже не пользуются солью. В PHP 5.5 был представлен новый API для хэширования, который не только поощряет применение bcrypt, но и существенно облегчает работу с ним. Давайте разберём основы использования этого нового API.

password_hash()

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

Функция password_hash() существенно облегчает разработчику жизнь и повышает безопасность кода. Для хэширования пароля достаточно скормить его функции, и она вернёт хэш, который можно поместить в БД:

И всё! Первый аргумент — пароль в виде строки, второй аргумент задаёт алгоритм генерирования хэша. По умолчанию используется bcrypt, но при необходимости можно добавить и более сильный алгоритм, который позволит генерировать строки большей длины. Если в своём проекте вы используете PASSWORD_DEFAULT, то удостоверьтесь, что ширина колонки для хранения хэшей не менее 60 символов. Лучше сразу задать 255 знаков. В качестве второго аргумента можно использовать PASSWORD_BCRYPT. В этом случае хэш всегда будет длиной в 60 символов.

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

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

password_verify()

Теперь рассмотрим функцию сравнения пароля с хэшем. Первый вводится пользователем, а второй мы берём из БД. Пароль и хэш используются в качестве двух аргументов функции password_verify(). Если хэш соответствует паролю, то функция возвращает true.

Помните, что соль является частью хэша, поэтому она не задаётся здесь отдельно.

password_needs_rehash()

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

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

password_get_info()

Более ранние версии PHP

Как видите, работать с новым API не в пример легче, чем с неуклюжей функцией crypt(). Если же вы используете более ранние версии PHP, то рекомендую обратить внимание на библиотеку password_compact. Она эмулирует данный API и автоматически отключается, когда вы обновляетесь до версии 5.5.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *