Шифрование данных в веб-приложении: разбор сбоя ключей
После ротации ключа приложение перестало расшифровывать часть данных — хотя база и сервер оставались доступны. Разбираем такой типовой сценарий: где искать причину, как ограничить ущерб и что измерить до следующего переключения.

После ротации ключа веб-приложение может продолжать отвечать на запросы, но возвращать ошибки там, где нужно расшифровать пользовательские данные. Это не описание конкретной компании или опубликованного инцидента, а разбор типового сценария: в PostgreSQL 16 зашифрованные поля доступны, но сервис потерял совместимость с ключом, которым их записали. Ошибка в архитектуре способна превратить плановое обновление защиты в недоступность данных.
Как выглядит сбой
Представим приложение, которое шифрует часть полей до записи в базу, например контактные данные. Шифротекст попадает в PostgreSQL, а ключ хранится отдельно от базы. При ротации команда разворачивает новый ключ и удаляет или отключает старый. Новые записи шифруются, но старые по-прежнему требуют прежнего ключа. При чтении сервис не может их расшифровать.
Симптомы могут быть неравномерными: одни профили открываются, другие вызывают ошибку; запись новых данных работает, чтение старых — нет. Если приложение скрывает ошибку общим ответом, проблема выглядит как сбой базы, хотя соединение с ней исправно. Важно не смешивать этот сценарий с компрометацией ключа: причины и действия при утечке будут другими.
Шифрование защищает данные только пока приложение умеет управлять ключами. Потерянный ключ может сделать ваши собственные данные нечитаемыми не хуже, чем злоумышленник.
Что проверить в первую очередь
Не начинайте с массового обновления записей и повторной генерации ключей. Сначала сохраните логи и установите, какой слой отказал: TLS-соединение, доступ к базе, получение ключа или собственно расшифровка. В логах не должно быть самих ключей, открытых персональных данных и полного шифротекста.
- Сопоставьте время ошибки с изменениями. Проверьте деплой приложения, обновление переменных окружения и настройки хранилища ключей. Успешный запуск новой версии не доказывает, что она читает данные, созданные старой.
- Проверьте доступ к источнику ключей. Сервис мог потерять разрешение или не получить нужную версию секрета. Отделяйте ошибку доступа от ошибки расшифровки: это разные причины и разные исправления.
- Уточните, какие записи затронуты. Сверьте время и версию ключа для успешно читаемых и проблемных записей, если приложение сохраняет такие метаданные. Не выводите содержимое полей в диагностический лог.
- Проверьте восстановление на копии. Возьмите резервную копию и доступную копию нужного ключа, затем попробуйте прочитать тестовую запись в изолированной среде. Проверка только наличия файлов резервной копии не подтверждает, что данные можно восстановить.
- Остановите опасные изменения. Не удаляйте старые ключи и не перезаписывайте поля, пока не выяснено, какие данные ими зашифрованы. Успех — известен диапазон затронутых записей и сохранены материалы для восстановления.
Термин — конвертное шифрование. Данные шифрует отдельный ключ данных, а ключ данных защищает основной ключ, которым управляет выделенное хранилище. Такой подход позволяет менять защиту ключа отдельно от массового перешифрования записей, но усложняет хранение версий и процедуру восстановления.
Где проходит граница защиты
Шифрование передачи и шифрование хранимых данных решают разные задачи. TLS 1.3 защищает соединение между клиентом и сервером или между сервисом и базой от перехвата в пути. Но TLS сам по себе не защищает файл базы, резервную копию или данные от приложения, которое уже получило к ним доступ.
Для PostgreSQL 16 шифрование соединений настраивают отдельно; сам PostgreSQL не превращает все файлы базы на диске в зашифрованные. Защиту дисков и резервных копий нужно проектировать на соответствующих слоях. Если приложение должно скрывать отдельные поля даже от части инфраструктуры базы, шифрование на уровне приложения может это обеспечить, но ключи тогда становятся критической зависимостью самого сервиса.
| Мера | Что защищает | Где ломается |
|---|---|---|
| TLS 1.3 | Данные при передаче по сети между участниками соединения | Не закрывает файлы базы и не спасает от приложения, получившего доступ к открытым данным |
| Шифрование диска или хранилища | Файлы на носителе и, при правильной настройке, его резервные копии | Не мешает работающему сервису читать данные через смонтированную систему |
| Шифрование полей в приложении | Выбранные поля до записи в базу | Зависит от доступности ключей, совместимости версий и корректного восстановления |
Таблица описывает типовые границы, а не гарантии конкретного облачного провайдера. Перед внедрением проверьте, какие именно слои шифрует ваша платформа и входят ли резервные копии в тот же контур защиты.
Почему ротация ключа превращается в инцидент
Частая причина — приложение знает только один текущий ключ. После переключения оно пытается применить его и к старым записям. Другой вариант: старый ключ удалили раньше, чем закончили миграцию. Наконец, ключ может сохраниться, но сервис потеряет доступ к его версии из-за изменения прав или конфигурации.
Для каждой зашифрованной записи стоит хранить идентификатор версии ключа или другой способ однозначно выбрать нужную версию. Это не секрет и не сам ключ. Приложению нужна контролируемая возможность читать старые версии, а создавать новые записи — уже с новой. Старый ключ удаляют только после проверки, что данные больше от него не зависят и восстановление проверено.
При этом не стоит считать ротацию автоматическим лечением утечки. Если ключ скомпрометирован, нужно определить объём доступа и период риска, ограничить использование ключа, сохранить доказательства и действовать по плану реагирования. Простая замена секрета не отменяет того, что доступные ранее данные могли быть расшифрованы.
Что измерять и где решение ломается
Универсальных цифр производительности здесь нет: результат зависит от алгоритма, объёма полей, частоты чтения, реализации и инфраструктуры. Перед запуском измерьте на копии репрезентативных данных время чтения и записи с шифрованием и без него, загрузку CPU, долю ошибок расшифровки и задержку обращения к хранилищу ключей. Зафиксируйте объём данных, конфигурацию сервера и параллельность запросов — иначе сравнение до и после будет мало полезно.
- Если хранилище ключей недоступно, новые операции могут остановиться; заранее определите, какие запросы можно безопасно отклонить, а какие данные допустимо временно не показывать.
- Если резервная копия сохранена, но ключ к ней утрачен, копия не решает задачу восстановления. Проверяйте вместе и данные, и ключевой материал.
- Если приложение кэширует открытые данные, срок жизни кэша влияет на то, как быстро пользователи увидят изменение прав или блокировку доступа.
- Если шифрование поля мешает поиску и индексированию, не ослабляйте его незаметно ради удобства. Отдельно проектируйте допустимые запросы и утечки метаданных.
Граница подхода проста: шифрование полей не защищает от кода приложения, который уже законно получает открытое значение. Оно также не скрывает автоматически факт существования записи, размер данных или частоту обращений.
Что делать дальше
Для действующего сервиса начните с инвентаризации: какие данные шифруются, где лежат ключи, какие версии ещё нужны для чтения и кто может их получить. Затем проведите учение по восстановлению на копии базы PostgreSQL 16: отключите тестовый сервис от текущего ключа, восстановите доступ по документированной процедуре и убедитесь, что старые записи читаются. В мониторинге отдельно отслеживайте ошибки получения ключа и ошибки расшифровки, не записывая секреты в журналы. Следующий отдельный вопрос — ротация с перешифрованием данных; здесь важны порядок миграции и проверка отката.
Аналитик звонков: Разбор записи звонка по этапам сделки: где сорвалось, что упущено, три исправляемые рекомендации с цитатами.
Спросить за 90 ₽Источники: PostgreSQL 16: SSL Support, RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3
Частые вопросы
Если старый ключ уже удалили, можно ли вернуть данные?
Достаточно ли включить TLS, чтобы защитить базу?
Можно ли удалить старый ключ сразу после ротации?
Что делать, если ошибки расшифровки появились после деплоя?
Эти рекомендации подходят для другой версии PostgreSQL?
Как понять, что резервная копия действительно пригодна?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.