MD5 и семейство SHA-1 исторически применялись для контроля целостности данных и быстрых вычислений контрольных сумм. Однако их использование для хранения паролей приводит к критическим уязвимостям. Основная проблема заключается в высокой скорости вычисления и отсутствии механизмов адаптации к вычислительной мощности атакующего.
MD5:
SHA-1:
SHA-2 (SHA-256, SHA-512), несмотря на криптографическую устойчивость к коллизиям, также не подходит для хранения паролей по причине высокой скорости вычисления.
Хеширование паролей требует не только необратимости, но и сопротивления массовому перебору. MD5 и SHA позволяют выполнять миллиарды операций в секунду на современной GPU-инфраструктуре, что делает перебор словарей и brute-force атаки практически неограниченно эффективными.
Ключевые проблемы:
Полный перебор всех возможных комбинаций становится реалистичным при использовании быстрых хеш-функций.
Используются базы распространённых паролей и утёкших данных.
Предварительно вычисленные таблицы соответствий «хеш → пароль», особенно эффективные против MD5 и SHA без соли.
Современные схемы хранения паролей строятся вокруг следующих принципов:
Наиболее распространённые алгоритмы:
Библиотека Password-hash в JavaScript используется как абстракция над криптографическими алгоритмами хеширования паролей и механизмами проверки. Её назначение — унификация работы с различными стратегиями хранения паролей и упрощение перехода от устаревших схем.
Типовая функциональность:
Архитектурно Password-hash выступает как слой совместимости между legacy-системами (MD5/SHA) и современными алгоритмами (bcrypt/argon2).
Миграция с MD5/SHA требует сохранения обратной совместимости с существующей базой пользователей. Полная перерасчётная миграция паролей невозможна без знания исходных значений, поэтому используется стратегия постепенного обновления.
Основные принципы перехода:
Гибридная схема позволяет одновременно поддерживать старые и новые методы:
Такая модель постепенно очищает базу от устаревших хешей без принудительного сброса паролей.
Типичная запись пользователя в базе может включать:
JavaScript-ориентированная логика может быть построена вокруг единой точки проверки:
import PasswordHash from "password-hash";
function verifyPassword(inputPassword, storedRecord) {
if (storedRecord.algorithm === "md5") {
const legacyHash = md5(inputPassword);
const isValid = legacyHash === storedRecord.hash;
if (isValid) {
const newHash = PasswordHash.generate(inputPassword, {
algorithm: "argon2"
});
updateUserHash(storedRecord.userId, {
hash: newHash.hash,
algorithm: "argon2",
salt: newHash.salt
});
}
return isValid;
}
if (storedRecord.algorithm === "bcrypt") {
return PasswordHash.verify(inputPassword, storedRecord.hash);
}
return false;
}
Соль предотвращает использование заранее вычисленных таблиц и делает каждый хеш уникальным. При переходе с MD5/SHA часто возникает проблема отсутствия соли в старых данных, что усиливает необходимость немедленной миграции при первом успешном входе пользователя.
При проектировании перехода учитываются следующие факторы:
Эволюция обычно проходит этапы:
Каждый следующий этап увеличивает стоимость атаки и снижает вероятность компрометации данных.
Несмотря на криптографическую стойкость, SHA-256 остаётся неподходящим для паролей из-за:
Использование SHA-256 допустимо только в составе HMAC или специализированных конструкций, но не как самостоятельный механизм хранения паролей.
Современная система хранения паролей строится на следующих компонентах:
Такая модель позволяет трансформировать систему без нарушения пользовательского доступа и без массового сброса паролей.