Содержание
В веб-проекте шифрование нужно на трёх уровнях: при передаче данных — HTTPS везде, включая внутренние соединения; при хранении — шифрование дисков, резервных копий и файлового хранилища; и на уровне отдельных полей базы — для паспортных данных, токенов и другой особо чувствительной информации. Пароли при этом не шифруют, а хешируют. Самое сложное в шифровании — не алгоритмы, а безопасное хранение ключей.
Разберём, что и где шифровать, чем шифрование отличается от хеширования и как управлять ключами.
Чем шифрование при передаче отличается от шифрования при хранении?
Шифрование при передаче защищает данные, пока они идут по сети: от браузера до сервера, от приложения до базы, от сервиса к сервису. Шифрование при хранении защищает данные, которые лежат на дисках, в резервных копиях и хранилищах, — на случай кражи диска, утечки бэкапа или доступа к хранилищу.
| Уровень | Что защищает | Как реализуют |
|---|---|---|
| При передаче | Перехват трафика | HTTPS/TLS для сайта, API, базы и внутренних сервисов |
| Диски и тома | Кражу или утилизацию дисков | Шифрование дисков у провайдера или в ОС |
| Резервные копии | Утечку бэкапов | Шифрование архивов, ключ отдельно от копий |
| Поля базы | Доступ к базе через SQL-инъекцию или дамп | Шифрование в приложении перед записью |
| Файлы | Утечку хранилища | Шифрование на стороне сервера или приложения |
Почему пароли хешируют, а не шифруют?
Пароли хешируют, потому что их никогда не нужно расшифровывать: при входе достаточно сравнить хеш введённого пароля с сохранённым. Зашифрованный пароль можно расшифровать, если украден ключ, а хеш — нельзя. Использовать нужно медленные алгоритмы с солью, а не быстрые вроде MD5 или SHA-256.
// Регистрация: сохраняем только хеш (bcrypt или argon2id)
$user->password = Hash::make($request->password);
// Вход: сравниваем введённый пароль с хешем
if (! Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages(['email' => 'Неверный логин или пароль']);
}
Медленные алгоритмы bcrypt и argon2id делают перебор утёкших хешей очень дорогим. Ещё надёжнее — не хранить пароли вовсе и перейти на passkeys, подробнее в статье двухфакторная аутентификация и passkeys.
Фото: Unsplash
Какие поля стоит шифровать в базе?
Отдельно шифровать в базе стоит данные, утечка которых особенно опасна и которые не нужны для поиска и сортировки: паспортные данные, ИНН и СНИЛС, медицинскую информацию, токены доступа к сторонним сервисам, секретные ключи пользователей. Тогда даже полный дамп базы без ключа будет бесполезен.
Что учесть:
- Поиск. По зашифрованному полю нельзя искать — для точного поиска храните отдельный хеш с секретом.
- Сортировка и отчёты. Зашифрованные значения нельзя сортировать и группировать в SQL.
- Ключ вне базы. Ключ хранится в менеджере секретов или переменных окружения, а не рядом с данными.
- Версия ключа. Вместе с данными сохраняйте идентификатор ключа — это упрощает ротацию.
Номера банковских карт лучше не хранить вовсе: их принимает платёжный провайдер, а у вас остаётся только токен. Подробнее — в статьях как подключить онлайн-оплату и разработка финтех-продукта.
Как управлять ключами шифрования?
Ключ шифрования ценнее самих данных: тот, у кого есть ключ и доступ к базе, прочитает всё. Поэтому ключи хранят отдельно от данных, выдают только тем сервисам, которым они нужны, и регулярно меняют.
- храните ключи в менеджере секретов или облачной службе управления ключами, а не в коде;
- используйте разные ключи для разных окружений и разных типов данных;
- журналируйте использование ключей;
- отработайте ротацию: новый ключ, перешифрование, отзыв старого;
- обеспечьте резервное копирование ключей — без ключа зашифрованные бэкапы не восстановить.
Подробнее о хранении — статья секреты в проекте.
Что проверить в своём проекте?
Минимальный набор проверок занимает пару часов и закрывает самые распространённые проблемы. Его стоит пройти перед запуском и после крупных изменений инфраструктуры.
- HTTPS на всех доменах с перенаправлением с HTTP и заголовком HSTS;
- TLS между приложением и базой, кешем и очередями, если они на разных серверах;
- шифрование дисков и резервных копий включено;
- пароли хешируются bcrypt или argon2id;
- чувствительные поля зашифрованы, ключ хранится отдельно;
- персональные данные не попадают в логи — подробнее в статье персональные данные на сайте.
Коротко
- Шифруйте данные при передаче, при хранении и на уровне особо чувствительных полей.
- Пароли хешируют медленными алгоритмами с солью, а не шифруют.
- Шифрование полей мешает поиску и сортировке — шифруйте только то, что действительно нужно.
- Ключи хранят отдельно от данных, с журналом доступа и отработанной ротацией.
- Номера карт не храните вовсе — пусть их принимает платёжный провайдер.
Частые вопросы
Замедляет ли шифрование работу сайта?
Практически нет. Современные процессоры шифруют аппаратно, а TLS 1.3 и HTTP/2 даже ускоряют загрузку по сравнению со старыми протоколами. Шифрование полей добавляет микросекунды на запись.
Можно ли искать по зашифрованным полям?
Напрямую — нет. Для точного поиска рядом хранят хеш значения с секретной солью и ищут по нему. Полнотекстовый поиск по зашифрованным данным требует специальных решений.
Что делать, если ключ шифрования утёк?
Выпустить новый ключ, перешифровать данные и отозвать старый, а затем выяснить, как произошла утечка. Поэтому процесс ротации ключей должен быть отработан заранее, а не придумываться во время инцидента.



