Миграция Процесса Хеширования Паролей без Простоев. Начало
Требования к безопасности постоянно меняются. То, что считалось «достаточно безопасным» пять лет назад, сегодня может не пройти проверку безопасности. Необходимо перейти на современный алгоритм, такой как Argon2 или Bcrypt. Но вот в чем проблема: хеширование — односторонняя операция. Нельзя переделать существующий хэши под другой алгоритм. А если просто заменить реализацию IPasswordHasher, вы сломаете приложение. Каждый существующий пользователь, пытающийся войти в систему, не пройдёт аутентификацию, потому что новый хэш не совпадёт со старым. Рассмотрим миграцию процесса хеширования без простоев на практике.
Реальные системы имеют больше ограничений (и не следует создавать аутентификацию с нуля). Но это наглядный пример шаблона, который можно повторно использовать для миграции БД:
- Переход от старого формата к новому;
- Сохранение работоспособности существующего поведения;
- Поэтапная миграция данных;
- Удаление устаревших данных только после завершения миграции.
Наивный подход и проблемы с ним
Представим, что у вас есть простая система аутентификации. Вы хотите заменить устаревший хэш PBKDF2 стандартной реализацией Argon2. Можно попытаться просто зарегистрировать новую реализацию в DI-контейнере:
// Меняем LegacyHasher на NewHasher
builder.Services.AddSingleton<IPasswordHasher, NewHasher>();
Cценарий сбоя
Новые пользователи: регистрируются и входят в систему без проблем. Их пароли сразу хэшируются с помощью Argon2.
Существующие пользователи: Пользователь вводит свой правильный пароль. Система извлекает старый хэш PBKDF2 из БД.
Сбой: NewHasher пытается проверить хэш PBKDF2 и терпит неудачу, возвращая ошибку 401 Unauthorized.
Нам нужен способ одновременной поддержки обоих алгоритмов без усложнения кода авторизации.
Решение: Миграция при входе в систему
Стратегия проста: мигрируем пользователей постепенно, по мере подтверждения ими своей личности.
Последовательность действий
Попытка 1: Пытаемся проверить пароль с использованием нового алгоритма.
Попытка 2 (резервный вариант): Если это не удаётся, проверяем, может ли устаревший алгоритм проверить пароль.
Миграция: Если проверка по старому алгоритму прошла успешно:
1) Даём пользователю доступ в систему.
2) Перехэшируем его пароль, используя новый алгоритм.
3) Обновляем запись в БД.
Впоследствии при входе этого пользователя в систему проверка будет осуществляться по новому алгоритму.
Далее рассмотрим реализацию этого алгоритма.
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/a-practical-demo-of-zero-downtime-migrations-using-password-hashing