Хеш как строковое поле: длина и тип колонки

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

Большинство алгоритмов хеширования для паролей (bcrypt, Argon2, scrypt, PBKDF2) возвращают результат в текстовом виде. Это связано с тем, что:

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

Типичная строка хеша включает:

  • идентификатор алгоритма;
  • параметры работы (cost factor, memory, iterations);
  • соль;
  • сам хеш.

Например, bcrypt-хеш имеет структуру:

$2b$10$..............................................

Именно поэтому он занимает фиксированную длину — 60 символов.

Длина строки и её значение для схемы базы данных

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

bcrypt

  • фиксированная длина: 60 символов
  • включает соль и параметры cost
  • рекомендуется использовать тип:
VARCHAR(60)

или с запасом:

VARCHAR(100)

(если предполагается миграция на другой алгоритм в будущем)

Argon2

Argon2 формирует более длинные строки, содержащие параметры памяти, итераций и соль. Типичная длина:

  • от 95 до 200+ символов (в зависимости от реализации)

Рекомендуемая колонка:

VARCHAR(255)

или

TEXT

PBKDF2 / scrypt

Длина зависит от:

  • длины соли
  • формата кодирования (hex/base64)
  • количества итераций и выходной длины

В среднем:

  • 128–512 символов

На практике используется:

VARCHAR(512)

или TEXT

Выбор между VARCHAR и TEXT

Выбор типа колонки влияет не только на хранение, но и на индексирование и производительность.

VARCHAR

Используется, когда:

  • длина хеша ограничена или предсказуема;
  • требуется индексирование;
  • важна валидация длины на уровне БД.

Преимущества:

  • быстрее индексация;
  • контроль максимального размера;
  • компактность хранения.

Недостатки:

  • необходимость заранее закладывать запас длины.

TEXT

Используется, когда:

  • длина хеша может изменяться в зависимости от алгоритма;
  • планируется поддержка разных форматов;
  • важна гибкость миграций.

Особенности:

  • обычно не индексируется полностью;
  • может иметь ограничения в ORM или драйверах;
  • не требует точного задания длины.

Кодирование хеша: hex, base64 и их влияние

Формат представления напрямую влияет на длину строки.

Hex-кодирование

  • 1 байт = 2 символа
  • увеличивает размер на ~100%

Используется реже в современных системах из-за неэффективности.

Base64

  • более компактное представление
  • стандарт для большинства современных библиотек

Пример:

  • 32 байта → ~44 символа base64

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

Практика проектирования колонок в SQL

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

Пример универсальной схемы:

password_hash VARCHAR(255) NOT NULL

или более строгий вариант:

password_hash VARCHAR(100) NOT NULL

если используется исключительно bcrypt.

Ограничения и защита целостности

Для предотвращения повреждения данных применяются ограничения:

CHECK по длине

CHECK (LENGTH(password_hash) >= 20)

или более строго:

CHECK (LENGTH(password_hash) BETWEEN 50 AND 255)

NOT NULL

Хеш пароля никогда не должен быть NULL, так как это нарушает модель безопасности.

Индексация и хеш пароля

Хеши паролей:

  • не индексируются для поиска;
  • используются только для сравнения при аутентификации.

Индексирование колонки password_hash не имеет смысла и увеличивает накладные расходы при записи.

Влияние ORM и библиотек JavaScript

При использовании Node.js-экосистемы (Sequelize, TypeORM, Prisma) важно учитывать, что некоторые ORM:

  • по умолчанию ограничивают длину VARCHAR;
  • могут автоматически изменять тип на TEXT при миграциях;
  • не валидируют длину хеша на уровне модели.

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

Ошибки, связанные с длиной поля

На практике встречаются следующие проблемы:

  • обрезание хеша при INSERT (silent truncation);
  • несовместимость при миграции bcrypt → Argon2;
  • потеря параметров алгоритма;
  • различие кодировок (UTF-8 vs Latin1);
  • неожиданные ошибки сравнения строк при collation-sensitive настройках.

Особенно опасна ситуация, когда база данных не выбрасывает ошибку при переполнении VARCHAR, а просто обрезает значение.

Сравнение подходов хранения

Алгоритм Рекомендуемый тип Длина Причина
bcrypt VARCHAR 60–100 фиксированная структура
Argon2 VARCHAR/TEXT 95–255+ переменная длина
PBKDF2 VARCHAR/TEXT 128–512 зависит от параметров
scrypt VARCHAR/TEXT 128–512 высокая вариативность

Миграционные стратегии

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

Распространённый подход:

  1. установить VARCHAR(255) или TEXT;
  2. хранить в строке идентификатор алгоритма;
  3. поддерживать несколько форматов одновременно;
  4. выполнять постепенную миграцию при входе пользователя.

Такой подход исключает необходимость изменения схемы базы при обновлении криптографического стандарта.