Шифрование данных в базах данных: методы, инструменты и управление ключами | AdminWiki

Шифрование данных в базах данных: методы, инструменты и управление ключами

17 сентября 2026 13 мин. чтения
Содержание статьи

Что такое шифрование данных в базах данных и зачем оно нужно

Шифрование данных в базе данных переводит содержимое таблиц, журналов транзакций и файлов данных в нечитаемый набор байтов, который нельзя расшифровать без ключа. Ключ хранится отдельно от данных, поэтому копия каталога data, украденный снапшот тома или дамп базы без ключа бесполезны для атакующего. Расшифровка идёт в момент чтения: силами СУБД либо в приложении до попадания данных в таблицу.

Практический ответ на главный вопрос: метод выбирают по модели угроз, а не по названию технологии. Защита от кражи диска или снапшота закрывается прозрачным шифрованием (TDE). Когда администратор базы не должен видеть номера карт и паспортные данные, нужен столбцовый уровень или шифрование в приложении. Три уровня решают разные задачи, и в одной системе они часто работают вместе.

Прозрачное шифрование шифрует файлы данных и журналы целиком, приложение об изменениях не знает. Шифрование на уровне столбцов закрывает конкретные поля вызовами функций СУБД. Шифрование на стороне приложения выполняется до отправки INSERT, и СУБД ключей не видит вообще. Любой из методов закрывает один класс рисков, утечку носителя или копии данных, и не отменяет управление доступом, аудит и защиту соединений.

Цифры показывают масштаб проблемы. В отчёте Verizon DBIR 2024 на человеческий фактор приходится 68% утечек, а IBM оценила среднюю стоимость утечки в 2024 году в 4,88 млн долларов. Утечка шифрованного дампа без ключей не превращается в инцидент с уведомлением регулятора и клиентов, а восстановление репутации обходится дороже самой защиты.

Перед включением шифрования полезно навести порядок в правах: ревизия привилегий и настроек соединений разобрана в материале про аудит безопасности PostgreSQL, MySQL и MongoDB в 2026 году. Дальше: сравнительная таблица трёх уровней, пошаговые примеры для PostgreSQL, MySQL и MongoDB, управление ключами через KMS, замеры производительности и критерии выбора.

Три уровня шифрования: TDE, шифрование на уровне столбцов и на стороне приложения

Сравнение начинается с модели угроз. Если злоумышленник получает физический доступ к диску, съёмную копию снапшота или архив резервной копии, поможет любой из трёх уровней. Если открытые данные доступны администратору базы, TDE не спасает: расшифровка идёт внутри СУБД, и SELECT вернёт открытый текст. Разница между уровнями видна в таблице.

КритерийTDEШифрование столбцовШифрование в приложении
Что шифруетсяФайлы данных, журналы, временные файлыОтдельные поля таблицДанные до отправки в СУБД
Где хранятся ключиKeyring СУБД, внешний KMS, HSMПриложение или keyring, ключ передаётся в запросеТолько приложение, KMS или Vault
Кто видит открытый текстЛюбой пользователь с правом SELECTЛюбой, кто знает ключ и имеет право SELECTТолько приложение с ключом
Защита от недобросовестного DBAНетЧастичноДа
Индексы и поискРаботают без измененийОбычные индексы и LIKE недоступныПоиск и сортировка только в приложении
Изменения в приложенииНе требуютсяПравки запросов на чтение и записьПереработка логики работы с полями
Overhead5-15% на дисковом вводе-выводе20-30% на операциях с полямиоколо 40% в приложении
PostgreSQLРасширение pg_tde от Percona, в core нетpgcryptoбиблиотека cryptography и аналоги
MySQLEnterprise TDE и Percona ServerAES_ENCRYPT и AES_DECRYPTлюбая библиотека
MongoDBШифрование на уровне хранилищаCSFLE, Queryable Encryptionлюбая библиотека в драйвере

Прозрачное шифрование данных (TDE): когда оно оправдано

TDE защищает данные на диске (data at rest) и не защищает от SQL-инъекций, ошибок в приложении и администратора с доступом к памяти процесса. Расшифровка идёт на уровне страниц InnoDB или файлов данных, ключи подгружаются при старте СУБД, поэтому доступность keyring критична: без него база просто не откроется.

MySQL Enterprise включает TDE с плагинами keyring_file и keyring_okv. Файловый keyring_file годится для тестового стенда, для продакшена берут Oracle Key Vault или внешний KMS. Percona Server for MySQL поддерживает TDE с плагином keyring_vault и держит мастер-ключ в HashiCorp Vault. Приложение правок не требует, планы запросов не меняются. Расплата: зашифровать отдельные столбцы нельзя, а логи и бэкапы нуждаются в отдельной настройке.

В PostgreSQL TDE в core отсутствует. Расширение pg_tde от Percona долгое время находилось в статусе беты и умеет шифровать таблицы через keyring-файл. Для продакшена без сторонних расширений остаются столбцовое шифрование или защита тома средствами операционной системы, например LUKS. Клиентские и серверные модели шифрования с гибридными схемами разобраны в руководстве про шифрование данных при передаче и хранении.

Шифрование на уровне столбцов: гибкость и компромиссы

Столбцовое шифрование закрывает конкретные поля: номер карты, СНИЛС, паспортные данные, токен доступа. Остальные колонки остаются открытыми, обычные индексы и аналитика продолжают работать. Ключ передаётся в функцию шифрования, поэтому главный вопрос звучит так: откуда приложение берёт этот ключ. Если он лежит в той же базе или в конфиге рядом с ней, защита теряет смысл.

Ограничения проявляются на этапе запросов. Зашифрованный текст нельзя поместить в B-tree индекс, сравнить операторами больше и меньше, найти через LIKE. Диапазонные отчёты по таким полям приходится строить в приложении. Детерминированное шифрование даёт одинаковый шифротекст для одинаковых значений и разрешает поиск равенством, order-preserving шифрование сохраняет порядок, но обе схемы снижают стойкость: атакующий видит частотные закономерности.

Шифрование на стороне приложения: максимальная защита

При шифровании в приложении открытый текст не покидает код сервиса. СУБД получает готовый шифротекст, ключей не знает и не может расшифровать его даже по прямому запросу администратора. Так закрывается угроза недобросовестного DBA, утечки дампа и доступа к снапшотам. Цена высокая: серверный поиск, агрегация и уникальность по зашифрованным полям ломаются, а ключи нужно выдавать приложению через KMS или Vault.

Библиотеки: cryptography и PyNaCl в Python, libsodium в C и Go, jose в JavaScript. Формат Fernet из библиотеки cryptography даёт AES-128-CBC с HMAC-SHA256 и проверкой целостности, что защищает от подмены шифротекста. Для новых проектов берут AES-256-GCM или ChaCha20-Poly1305: обе схемы аутентифицируют данные и не позволяют незаметно изменить зашифрованное значение.

Как зашифровать базу данных: пошаговые примеры для PostgreSQL, MySQL и MongoDB

Ниже рабочие команды для трёх СУБД. Перед любыми действиями снимите свежий бэкап и проверьте восстановление на отдельном стенде: включение шифрования меняет формат файлов и путь отката.

Шифрование в PostgreSQL: pgcrypto и pg_tde

Расширение pgcrypto входит в состав contrib и ставится одной командой:

CREATE EXTENSION IF NOT EXISTS pgcrypto;

Таблица и запись зашифрованного поля:

CREATE TABLE users (
  id serial PRIMARY KEY,
  name text,
  card bytea
);

INSERT INTO users (name, card)
VALUES ('Alice', pgp_sym_encrypt('1234567812345678', 'mysecretkey'));

SELECT name, pgp_sym_decrypt(card, 'mysecretkey')
FROM users;

Ключ уходит в тексте запроса и попадает в лог при log_statement = all. Передавайте его параметром через prepared statement либо шифруйте на стороне приложения и отправляйте в базу готовый bytea.

Для TDE применяют расширение pg_tde от Percona: оно подключается через shared_preload_libraries, создаёт keyring-файл и позволяет создавать таблицы с шифрованием страниц. Статус беты означает простую вещь: перед продакшеном нужен тест на вашей версии PostgreSQL и проверенная процедура восстановления.

Шифрование в MySQL: TDE и функции AES

TDE в Percona Server for MySQL включается через плагин keyring_vault. В my.cnf добавляются строки:

[mysqld]
early-plugin-load=keyring_vault.so
keyring_vault_config=/etc/mysql/vault-keyring.json

Файл vault-keyring.json содержит адрес Vault, токен и путь к секрету с мастер-ключом. После перезапуска создаётся зашифрованная таблица:

CREATE TABLE payments (
  id INT PRIMARY KEY,
  secret VARCHAR(255)
) ENCRYPTION='Y';

Проверка статуса шифрования:

SELECT NAME, ENCRYPTION
FROM information_schema.INNODB_TABLESPACES
WHERE ENCRYPTION = 'Y';

Для отдельных полей подходят функции AES_ENCRYPT и AES_DECRYPT. Режим по умолчанию, ECB, небезопасен: одинаковые блоки дают одинаковый шифротекст. Переключите режим перед работой:

SET GLOBAL block_encryption_mode = 'aes-256-cbc';

INSERT INTO users (card)
VALUES (AES_ENCRYPT('1234567812345678', 'mysecretkey'));

SELECT CAST(AES_DECRYPT(card, 'mysecretkey') AS CHAR) FROM users;

Плагин keyring_file подходит для стенда, где файл ключа лежит на том же сервере. Для продакшена держите мастер-ключ в Vault или HSM, иначе копия каталога data вместе с файлом ключа обнуляет всю защиту.

Шифрование в MongoDB: CSFLE и Queryable Encryption

Client-Side Field Level Encryption (CSFLE) требует MongoDB Enterprise или MongoDB Atlas. Приложение получает ключ данных из key vault, а драйвер сам шифрует поля по schema map. Пример на Python с pymongo:

from pymongo import MongoClient
from pymongo.encryption import ClientEncryption

client = MongoClient()
client_encryption = ClientEncryption(kms_providers, key_vault_namespace, client)

data_key_id = client_encryption.create_data_key(
    'aws', master_key={'region': 'us-east-1', 'key': 'arn:aws:kms:...'})

schema_map = {'db.users': {'fields': {
    'ssn': {'keyId': data_key_id, 'bsonType': 'string',
            'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}}

Детерминированный алгоритм даёт одинаковый шифротекст для одинаковых значений и разрешает поиск равенством. Случайный алгоритм безопаснее, но поиск по полю становится невозможен. Queryable Encryption доступна с MongoDB 7.0 в Enterprise и Atlas: поля помечаются как Indexed, и сервер выполняет запросы равенства по зашифрованным данным, не видя открытого текста. Atlas включает шифрование хранилища по умолчанию, поэтому для защиты от кражи диска отдельная настройка не нужна.

Управление ключами шифрования: как не потерять данные и сохранить доступность

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

Рабочая схема строится на двух уровнях ключей. Мастер-ключ (master key, он же KEK) лежит в KMS или HSM и никогда не покидает устройство. Ключи шифрования данных (data encryption key, DEK) шифруются мастер-ключом, и в базе хранится только их зашифрованная версия. Такой подход называют envelope encryption: он позволяет сменить мастер-ключ без перешифрования всех данных. Ключи не держат в каталоге data, не коммитят в git, не переносят в конфигах приложений.

Генерация идёт через криптографический источник случайности. Локально годится команда:

openssl rand -base64 32

Пароль человека в роли ключа не используется: его превращает в ключ функция вывода ключа (KDF). Соль, число итераций и выбор между PBKDF2, scrypt и Argon2 разобраны в статье про то, как пароль превращается в ключ шифрования.

Выбор KMS: HashiCorp Vault, AWS KMS и облачные решения

HashiCorp Vault подходит для on-premise и гибридных контуров: transit secrets engine выполняет шифрование и расшифровку, не отдавая ключ наружу. Базовая версия бесплатна, аудит доступа включается настройкой audit device. Минимальный набор команд для нового ключа:

vault secrets enable transit
vault write -f transit/keys/my-key
vault write transit/encrypt/my-key plaintext=SGVsbG8=

Облачные KMS (AWS KMS, GCP KMS, Azure Key Vault) снимают задачу обслуживания HSM, но привязывают к платформе: перенос базы в другой контур требует переноса ключей и проверки совместимости. Для развёртывания баз в облаке с шифрованием хранилища и отдельным хранилищем ключей подходит Timeweb Cloud: там доступны управляемые базы данных, объектное хранилище и Kubernetes, а политика шифрования задаётся на уровне сервиса. Включите аудит вызовов расшифровки: всплеск операций Decrypt в три часа ночи говорит о компрометации приложения.

Ротация ключей и восстановление после сбоев

Ротация делится на два вида. Смена мастер-ключа в KMS не трогает данные: DEK перешифровывается новым мастер-ключом, простой не нужен. Смена самого DEK требует перешифрования. В MySQL InnoDB ротация мастер-ключа выполняется командой:

ALTER INSTANCE ROTATE INNODB MASTER KEY;

Для столбцового шифрования перешифрование идёт пакетами: читаем строку, расшифровываем старым ключом, шифруем новым, записываем. На таблице в 10 млн строк при 1000 строк в секунду такой проход займёт около трёх часов, поэтому его запускают в часы низкой нагрузки. Плановая ротация раз в год для мастер-ключа и раз в квартал для данных держателей карт закрывает требования аудита.

При компрометации ключа порядок действий такой: сменить мастер-ключ, перешифровать DEK, проверить журналы доступа к KMS за последние недели, урезать права приложения на расшифровку. Если ключ утерян, но есть офлайн-копия в сейфе или зашифрованный бэкап ключа в KMS, база восстанавливается. Без копии ключа данные теряются необратимо: поднять TDE-файлы из бэкапа не получится.

Производительность и требования к шифрованию персональных данных

Ориентировочные цифры для планирования: TDE на процессорах с AES-NI даёт overhead 5-15% по дисковому вводу-выводу, шифрование столбцов добавляет 20-30% на операциях с зашифрованными полями, шифрование в приложении съедает около 40% времени обработки запроса. AES-NI есть в серверных процессорах Intel и AMD с 2010 года, поэтому деградация упирается в накладные расходы на вызовы функций и в рост размера зашифрованных значений, а не в сам алгоритм AES.

Как измерить влияние шифрования на производительность

Методика одинакова для любой СУБД. Сначала снимите baseline на реальной нагрузке: TPS, latency, загрузка CPU, объём записи на диск. Затем включите шифрование на копии продакшена и повторите замеры с теми же данными и темпом запросов. Разница в цифрах и есть цена защиты.

Для PostgreSQL используйте pgbench с пользовательским скриптом:

pgbench -c 10 -j 2 -T 60 -f script.sql -U postgres testdb

Для MySQL подойдёт sysbench:

sysbench oltp_read_write --db-driver=mysql --mysql-db=test --tables=10 --table-size=1000000 prepare
sysbench oltp_read_write --db-driver=mysql --mysql-db=test --tables=10 --table-size=1000000 run

Для MongoDB применяют YCSB с профилем workloada. Закладывайте запас 20-30% по CPU и по диску: после включения TDE растёт нагрузка на ввод-вывод, а при столбцовом шифровании часть работы переезжает с сервера в приложение, что меняет профиль потребления.

Соответствие 152-ФЗ, GDPR и PCI DSS: что выбрать

152-ФЗ (статья 19) обязывает принимать меры защиты персональных данных, включая шифрование при хранении и передаче. Для базы в защищённом контуре с ограниченным кругом администраторов аудиторы обычно принимают TDE вместе с политикой управления ключами. GDPR (статья 32) называет шифрование надлежащей мерой безопасности, конкретный алгоритм не задаёт. PCI DSS (требование 3.4) предписывает хранить номер карты только в нечитаемом виде и отдельно требует защиту ключей.

Практический вывод: если DBA не должен видеть номера карт, одного TDE недостаточно, нужен столбцовый уровень или шифрование в приложении. Аудиторы запрашивают три документа: политику управления ключами, журнал ротации и логи доступа к KMS. Подготовьте их заранее, иначе техническая часть окажется закрыта, а формальная нет.

Критерии выбора и типичные ошибки при внедрении шифрования

Решение принимается по пяти критериям. Модель угроз отвечает на вопрос, от кого защищаемся: от кражи диска, от недобросовестного администратора, от утечки через приложение. Требования регуляторов задают минимальный уровень. Допустимое падение производительности ограничивает выбор по железу. Сложность поддержки определяет, справится ли команда с ротацией и восстановлением. Бюджет на KMS и HSM закрывает список.

Готовые связки выглядят так. Защита от кражи диска и снапшотов: TDE в MySQL Enterprise или Percona Server, LUKS для тома PostgreSQL на Linux. Защита от недобросовестного DBA: шифрование на стороне приложения с ключами в Vault. Выборочная защита полей при сохранении серверного поиска по остальным данным: pgcrypto в PostgreSQL, AES_ENCRYPT в MySQL, CSFLE или Queryable Encryption в MongoDB. Шифрование резервных копий отдельным слоем: GnuPG, age и OpenSSL, их сравнение собрано в подборке программ и утилит для шифрования данных.

Ошибки, которые обесценивают защиту:

  • Ключ лежит рядом с данными, в том же каталоге, в конфиге приложения или в git. Копия сервера отдаёт атакующему и данные, и ключ.
  • Нет бэкапа ключей. Один сбой keyring-плагина превращает базу в набор нечитаемых страниц.
  • Слабые алгоритмы: AES-128 вместо AES-256, режим ECB, самодельные схемы на XOR и Base64.
  • Шифрование без ротации: ключ живёт годами, и утечка раскрывает исторические данные целиком.
  • Один ключ на все среды: данные из dev с тем же ключом открываются в prod.
  • Неполное покрытие: таблицу зашифровали, журналы, временные файлы и бэкапы забыли.
  • Отсутствие замеров: шифрование включают сразу в продакшене и получают деградацию в пиковые часы.

Чек-лист перед запуском шифрования:

  1. Определить, какие данные шифруются и от какой угрозы.
  2. Выбрать уровень: TDE, столбцы или приложение.
  3. Настроить KMS, завести мастер-ключ и политику доступа.
  4. Сделать и проверить бэкап данных и ключей, включая офлайн-копию.
  5. Протестировать на копии продакшена и замерить TPS и latency до и после.
  6. Составить план отката и порядок ротации ключей.
  7. Обучить команду и зафиксировать регламент в документации.

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

Поделиться:
Сохранить гайд? В закладки браузера