Хеширование паролей в JavaScript и серверных приложениях обычно
строится вокруг криптографических функций, таких как bcrypt, scrypt или
argon2. Библиотеки уровня password-hash или аналогичные
обёртки реализуют принцип однонаправленного преобразования: исходный
пароль превращается в строку фиксированного или псевдофиксированного
формата, которую невозможно восстановить обратно в исходное
значение.
Ключевое свойство таких хешей — детерминированность при одинаковых входных данных и соли и полная непредсказуемость результата при малейшем изменении входа. Даже минимальное отличие в символе пароля приводит к радикально другому хешу.
Именно эта особенность делает попытки индексирования хешей в базах данных специфичной задачей, которая часто воспринимается неправильно.
Индекс в реляционных базах данных — это структура данных, оптимизирующая поиск по определённому столбцу. Чаще всего используются:
Основная идея индекса — ускорение операций вида:
=)<, >,
BETWEEN)ORDER BY)Индекс работает эффективно, когда данные обладают структурируемой упорядоченностью или предсказуемым распределением, позволяющим быстро сузить область поиска.
На первый взгляд может показаться, что индекс по хешу пароля полезен, поскольку проверка авторизации — это операция сравнения:
SEL ECT * FR OM users WH ERE password_hash = ?
Однако в реальной архитектуре систем хранения паролей ситуация отличается:
Типичный сценарий авторизации:
SELECT password_hash FR OM users WHERE email = ?
Сначала находится пользователь, затем выполняется проверка хеша в
приложении. Индекс нужен на email, а не на
password_hash.
Хеш пароля не является полем, по которому выполняется выборка записей в массовом режиме. Он:
Индекс на поле, по которому нет массовых запросов, теряет смысл.
Хеш пароля обладает практически максимальной селективностью: каждое значение уникально (или почти уникально при правильной соли).
Но высокая селективность не всегда означает пользу для индекса. Если запрос всегда возвращает максимум одну строку, оптимизатор базы данных и без индекса выполнит проверку за константное время после поиска пользователя по другому индексу.
Современные схемы хеширования паролей используют соль — случайную строку, добавляемую к паролю перед хешированием.
hash = H(password + salt)
Это приводит к следующим последствиям:
Индекс становится формально допустимым, но практически бесполезным, потому что:
Криптографические хеши обладают свойством равномерного распределения по пространству значений. Это означает:
B-tree индекс в таких условиях начинает вести себя почти как случайный доступ:
В итоге индекс не ускоряет поиск, а добавляет накладные расходы на поддержку структуры.
Важно различать:
Hash-index предназначен для ускорения точного сравнения ключей, но:
Криптографический хеш, наоборот:
Даже если технически создать индекс по полю хеша пароля, возникают негативные эффекты:
Каждая регистрация или смена пароля требует:
Это увеличивает нагрузку без реального прироста производительности запросов.
Практически нет запросов вида:
Следовательно, индекс не обслуживает бизнес-логику.
Добавление индекса создаёт формальное ощущение оптимизации, но фактически:
В JavaScript-экосистеме библиотеки уровня password-hash
обычно реализуют:
Примерная логика:
const hash = passwordHash.generate(password);
const verify = passwordHash.verify(password, hash);
Здесь отсутствует необходимость в индексировании самого хеша, потому что:
Таким образом, хранение хеша — это операция хранения атрибута, а не механизм поиска.
Иногда возникает идея использовать индекс по хешу в следующих случаях:
Однако даже в этих сценариях:
В случае утечек используются специализированные структуры (например, bloom filters), а не индексы БД.
Часто встречается попытка оптимизации схемы хранения:
CRE ATE INDEX idx_password_hash ON users(password_hash);
Подобная конструкция не учитывает фундаментальные свойства данных:
В результате индекс:
Комбинация факторов приводит к тому, что индекс по хешу пароля оказывается нефункциональным:
В результате поле password_hash остаётся частью
защищённого хранилища данных, но не становится элементом поисковой или
индексной инфраструктуры базы данных.