Шифрование данных с pgcrypto

Расширение pgcrypto представляет собой набор криптографических функций для шифрования данных непосредственно в базе данных. Расширение pgcrypto позволяет шифровать данные на уровне отдельных столбцов или значений. Это обеспечивает дополнительный уровень защиты для чувствительных данных, таких как персональная информация, финансовые записи.

Подробнее см. в официальной документации PostgreSQL.

Установка и активация pgcrypto

Чтобы использовать расширение pgcrypto:

  1. Подключитесь к базе данных с правами суперпользователя или администратора.

  2. Активируйте расширение в базе данных, выполнив SQL-запрос:

    CREATE EXTENSION IF NOT EXISTS pgcrypto;

После активации функции pgcrypto можно использовать в SQL-запросах.

Основные возможности pgcrypto

pgcrypto предоставляет следующие криптографические функции:

  • симметричное шифрование — функции encrypt и decrypt для шифрования и расшифрования данных с использованием алгоритмов, таких как AES;

    -- Шифрование данных
    SELECT encrypt('sensitive_data', 'my_secret_key', 'aes') AS encrypted_data;
    
    -- Расшифрование данных
    SELECT decrypt(encrypted_data, 'my_secret_key', 'aes') AS decrypted_data;

    Функция encrypt шифрует строку 'sensitive_data' с использованием ключа 'my_secret_key' и алгоритма AES. Результат — зашифрованные данные в формате BYTEA.

    Функция decrypt расшифровывает ранее зашифрованные данные (encrypted_data) с использованием того же ключа 'my_secret_key' и алгоритма AES, возвращая исходную строку.

  • асимметричное шифрованиешифрование с использованием пары публичного и приватного ключей (RSA);
    -- Генерация ключей
    SELECT gen_random_bytes(16) AS key;
    
    -- Шифрование с публичным ключом
    SELECT public_key_encrypt('sensitive_data', public_key, 'rsa');

    Функция gen_random_bytes(16) генерирует случайную последовательность байтов длиной 16 байт, которая может использоваться как часть процесса создания ключей (например, для симметричного шифрования или как seed).

    Функция public_key_encrypt шифрует строку 'sensitive_data' с использованием публичного ключа и алгоритма RSA. Зашифрованные данные можно расшифровать только с помощью соответствующего приватного ключа.

    Примечание

    public_key_encrypt требует предварительно созданной пары ключей (публичного и приватного), что не показано в примере, но предполагается.


  • хеширование — функции для создания хешей с использованием алгоритмов MD5, SHA-1, SHA-256 и др.;
    SELECT digest('data_to_hash', 'sha256') AS hashed_data;

    Функция digest создаёт хеш строки 'data_to_hash' с использованием алгоритма SHA-256. Результат — строка фиксированной длины в формате BYTEA, представляющая хеш.

    Хеширование необратимо — из хеша нельзя восстановить исходные данные.

  • генерация случайных данных — функция gen_random_bytes для создания криптографически безопасных случайных последовательностей;  
    SELECT gen_random_bytes(32) AS random_bytes;

    Функция gen_random_bytes(32) генерирует случайную последовательность байтов длиной 32 байта. Эти данные криптографически безопасны, т.е. подходят для использования в криптографических операциях.

  • проверка паролей — функции для безопасного хранения и проверки паролей, например, crypt и gen_salt.
    -- Хеширование пароля
    SELECT crypt('user_password', gen_salt('bf')) AS hashed_password;
    
    -- Проверка пароля
    SELECT crypt('user_password', hashed_password) = hashed_password AS password_valid;

    Функция gen_salt('bf') генерирует случайную соль  для алгоритма хеширования Blowfish (bf). Соль добавляет случайность, чтобы одинаковые пароли имели разные хеши.

    Функция crypt хеширует пароль 'user_password' с использованием этой соли, создавая защищённый хеш пароля (hashed_password).

    Для проверки пароля повторно вызывается crypt с тем же паролем и сохранённым хешем. Если результат совпадает с hashed_password, пароль верный (password_valid = true).

Пример интеграции

Допустим, требуется зашифровать столбец credit_card_number в таблице users. Для этого создайте таблицу и используйте pgcrypto следующим образом:

-- Создание таблицы
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username TEXT NOT NULL,
    credit_card_number BYTEA
);

-- Вставка зашифрованных данных
INSERT INTO users (username, credit_card_number)
VALUES (
    'ivan_ivanov',
    encrypt('1234-5678-9012-3456', 'my_secret_key', 'aes')
);

-- Получение расшифрованных данных
SELECT
    username,
    decrypt(credit_card_number, 'my_secret_key', 'aes')::TEXT AS credit_card_number
FROM users
WHERE username = 'ivan_ivanov';

Рекомендации по использованию pgcrypto

  1. Управление ключами — храните ключи шифрования в безопасном месте, например, в специализированных сервисах управления секретами. Избегайте хранения ключей в коде приложения или в базе данных.

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

  3. Безопасность

    • используйте криптографически стойкие алгоритмы, такие как AES-256 и SHA-256. Регулярно обновляйте ключи и проверяйте их целостность;

    • включите TLS при создании кластера для защиты данных при передаче.