Зачем вообще хэшировать пароли?
В последние дни на хабре появились сообщения о том, что базы с хэшами паролей популярных сервисов попадают в руки злоумышленников (1), (2). Становится известно, что сервис linked.in использует метод хэширования SHA-1, а last.fm использует MD5. Большинство паролей представляют собой короткие словарные слова, а значит злоумышленник, имея хэш, сможет найти исходный пароль даже без брутфорса, просто воспользовавшись радужными таблицами.
Это серьёзное нарушение безопасности, несмотря на то, что многие разработчики считают, что сохранение хэша пароля вместо самого пароля способно защитить пользователей сервиса в случае утечки базы данных. Безусловно, это гораздо лучше, чем хранить пароли в открытом виде, но, очевидно, недостаточно безопасно. Метод BCrypt, в отличие от MD5 и SHA-1 не очень известен на просторах рунета, в русскоязычной википедии даже нет статьи о нём. Что же он из себя представляет?
Что такое BCrypt?
BCrypt это алгоритм криптографического хэширования, использующий метод шифрования Blowfish. Он использует секретный ключ K (Key Factor), позволяющий настраивать стойкость шифрования, и это выделяет его среди других алгоритмов хэширования. Возможность повысить криптостойкость в будущем, когда компьютеры станут гораздо более мощными, означает, что этот алгоритм может быть использован без оглядки на растущую мощность процессоров и размеры вычислительных ферм.
Медленно не значит плохо
BCrypt работает гораздо медленнее других методов хэширования, но его результат защищён гораздо сильнее. Ведь когда дело касается хэширования и шифрования, быстрее не означает лучше. Чем больше времени занимает шифрование, тем дольше будет длиться расшифровка. Популярный метод MD5 вычисляется настолько быстро, что на обычном ноутбуке можно вычислять десятки тысяч хэшей в секунду. А на мощном сервере — сотни тысяч и миллионы! Вся красота и лаконичность этого метода бессильна перед простым брутфорсом.
Почему бы не использовать соль?
Стандартная функция нахождения хэша MD5 имеет такой вид:
MD5(password)
От слова, являющегося паролем, вычисляется хэш, который и будет храниться в базе данных. Когда пользователь захочет залогиниться, от его пароля будет снова вычислен хэш и сравнён с тем, который лежит в базе. Если хэши совпадают, значит пароли тоже совпадают, и пользователю разрешается войти. Если злоумышленник уведёт базу с хэшами паролей, то он, используя радужные таблицы, быстро найдёт простые пароли, хэши которых там уже есть.
Функция нахождения хэша MD5 с солью имеет, например, такой вид:
MD5(MD5(password)+salt)
Сначала находится хэш слова, являющегося паролем. К этому хэшу дописывается соль (случайный набор симолов, уникальный для каждого пользователя) и от сочетания «хэш пароля + соль» снова находится хэш, который будет храниться в базе данных. Соль хранится в той же базе данных и используется для вычисления хэша каждый раз, когда пользователь логинится.
Теперь, если злоумышленник уведёт вашу базу с хэшами, радужные таблицы ему уже не помогут, так как по ним можно искать лишь хэши словарных слов или наборов цифр. В таком случае злоумышленник, скорее всего, воспользуется брутфорсом. Имея на руках хэш и соль, вооружившись быстрым процессором, он будет подбирать хэши до тех пор, пока не получит совпадение.
Что решит проблему?
С каждым годом методы шифрования и хэширования становятся всё более уязвимы благодаря закону Мура. А большинство пользователей всё также используют пароли, состоящие из одних букв в нижнем регистре. Тут нам и пригодится тот факт, что BCrypt вычисляется гораздо медленнее, чем MD5. Как написано в статье «How To Safely Store A Password», вычисление MD5 от пароля «yaaa» заняло на ноутбуке автора меньше микросекунды. А вычисление BCrypt с идентификационной фразой в 12 символов, заняло 0,3 секунды. Это разница в пять порядков. Есои нахождения пароля, захэшированного в MD5 займёт 40 секунд, то поиск пароля, зашифрованного BCrypt займёт около 12-ти лет. Кстати, сам автор MD5 просил больше не использовать его метод, называя его устаревшим.
Если в коде вашего сайта всё ещё встречается md5($password), скорее замените его чем-нибудь более безопасным.
Автор: Nougat