Spec-Zone.ru › MariaDB

API-интерфейс плагина шифрования

Для шифрования данных в MariaDB (шифрование данных в статическом хранилище) требуется использовать плагин управления ключами и шифрования (плагин управления ключами и шифрования). Эти плагины отвечают как за управление ключами шифрования, так и за фактическое шифрование и расшифрование данных.

MariaDB поддерживает использование нескольких ключей шифрования. Каждый ключ шифрования использует 32-битовое целое число в качестве идентификатора ключа. Если конкретный плагин поддерживает вращение ключей, то ключи шифрования также могут быть обновлены, что создает новую версию ключа шифрования.

Дополнительную информацию можно найти в статьях Шифрование данных в статическом хранилище и Управление ключами шифрования.

API-интерфейс плагина шифрования

API-интерфейс плагина шифрования был создан, чтобы позволить плагину:

  • реализовать управление ключами, предоставлять ключи шифрования серверу по запросу и изменять их в соответствии с внутренними правилами.
  • реализовать фактическое шифрование и расшифрование данных с использованием алгоритма, определенного плагином.

Вот как это отражается в API:

/* Returned from get_latest_key_version() */
#define ENCRYPTION_KEY_VERSION_INVALID (~(unsigned int)0)
#define ENCRYPTION_KEY_NOT_ENCRYPTED (0)

#define ENCRYPTION_KEY_SYSTEM_DATA 1
#define ENCRYPTION_KEY_TEMPORARY_DATA 2

/* Returned from get_key()  */
#define ENCRYPTION_KEY_BUFFER_TOO_SMALL (100)

#define ENCRYPTION_FLAG_DECRYPT 0
#define ENCRYPTION_FLAG_ENCRYPT 1
#define ENCRYPTION_FLAG_NOPAD 2

struct st_mariadb_encryption {
  int interface_version; /**< version plugin uses */

  /********************* KEY MANAGEMENT ***********************************/

  /**
    Function returning latest key version for a given key id.

    @return A version or ENCRYPTION_KEY_VERSION_INVALID to indicate an error.
  */
  unsigned int (*get_latest_key_version)(unsigned int key_id);

  /**
    Function returning a key for a key version

    @param key_id       The requested key id
    @param version      The requested key version
    @param key          The key will be stored there. Can be NULL -
                        in which case no key will be returned
    @param key_length   in: key buffer size
                        out: the actual length of the key

    This method can be used to query the key length - the required
    buffer size - by passing key==NULL.

    If the buffer size is less than the key length the content of the
    key buffer is undefined (the plugin is free to partially fill it with
    the key data or leave it untouched).

    @return 0 on success, or
            ENCRYPTION_KEY_VERSION_INVALID, ENCRYPTION_KEY_BUFFER_TOO_SMALL
            or any other non-zero number for errors
  */
  unsigned int (*get_key)(unsigned int key_id, unsigned int version,
                          unsigned char *key, unsigned int *key_length);

  /********************* ENCRYPTION **************************************/
  /*
    The caller uses encryption as follows:
      1. Create the encryption context object of the crypt_ctx_size() bytes.
      2. Initialize it with crypt_ctx_init().
      3. Repeat crypt_ctx_update() until there are no more data to encrypt.
      4. Write the remaining output bytes and destroy the context object
         with crypt_ctx_finish().
  */

  /**
    Returns the size of the encryption context object in bytes
  */
  unsigned int (*crypt_ctx_size)(unsigned int key_id, unsigned int key_version);
  /**
    Initializes the encryption context object.
  */
  int (*crypt_ctx_init)(void *ctx, const unsigned char *key, unsigned int klen,
                        const unsigned char *iv, unsigned int ivlen, int flags,
                        unsigned int key_id, unsigned int key_version);
  /**
    Processes (encrypts or decrypts) a chunk of data

    Writes the output to th dst buffer. note that it might write
    more bytes that were in the input. or less. or none at all.
  */
  int (*crypt_ctx_update)(void *ctx, const unsigned char *src,
                          unsigned int slen, unsigned char *dst,
                          unsigned int *dlen);
  /**
    Writes the remaining output bytes and destroys the encryption context

    crypt_ctx_update might've cached part of the output in the context,
    this method will flush these data out.
  */
  int (*crypt_ctx_finish)(void *ctx, unsigned char *dst, unsigned int *dlen);
  /**
    Returns the length of the encrypted data

    It returns the exact length, given only the source length.
    Which means, this API only supports encryption algorithms where
    the length of the encrypted data only depends on the length of the
    input (a.k.a. compression is not supported).
  */
  unsigned int (*encrypted_length)(unsigned int slen, unsigned int key_id,
                                   unsigned int key_version);
};

Первый метод используется для вращения ключей. Плагин, который не поддерживает вращение ключей — например, file_key_management — может возвращать фиксированную версию для любого допустимого идентификатора ключа. Обратите внимание, что он все равно должен возвращать ошибку для недопустимого идентификатора ключа. Версия ENCRYPTION_KEY_NOT_ENCRYPTED означает, что данные не должны шифроваться.

Второй метод используется для управления ключами, сервер использует его для получения ключа, соответствующего определенному идентификатору ключа и определенной версии ключа.

Последние пять методов связаны с шифрованием. Обратите внимание, что они принимают ключ для использования и идентификатор и версию ключа. Это необходимо, потому что сервер может вывести сессионный, пользовательский или табличный ключ из исходного ключа шифрования, возвращаемого get_key(), поэтому аргумент key не обязательно должен соответствовать ключу шифрования, как его знает плагин. С другой стороны, алгоритм шифрования может зависеть от идентификатора и версии ключа (и в плагине example_key_management он делает это), поэтому плагин должен знать их, чтобы иметь возможность зашифровать данные.

Методы шифрования являются необязательными — если они не заданы (как в плагине debug_key_management), сервер будет использовать AES_CBC по умолчанию.

Текущие плагины шифрования

Дерево исходного кода MariaDB содержит четыре плагина шифрования. Все эти плагины довольно просты и могут служить хорошими примерами API-интерфейса плагина шифрования.

file_key_management

Он считывает ключи шифрования из текстового файла. Он поддерживает два различных алгоритма шифрования. Он поддерживает несколько ключей шифрования. Он не поддерживает вращение ключей. Подробности можно найти в статье Плагин управления ключами шифрования.

Версии

Версия Статус Введено
1.0 Стабильная MariaDB 10.1.18
1.0 Gamma MariaDB 10.1.13
1.0 Alpha MariaDB 10.1.3

aws_key_management

Плагин AWS Key Management использует Amazon Web Services (AWS) Key Management Service (KMS) для генерации и хранения ключей AES на диске в зашифрованном виде с использованием основного ключа клиента (CMK), хранящегося в AWS KMS. При запуске MariaDB Server плагин расшифрует зашифрованные ключи, используя функцию API AWS KMS «Decrypt». Данные MariaDB затем будут шифроваться и расшифровываться с использованием ключа AES. Он поддерживает несколько ключей шифрования. Он поддерживает вращение ключей.

Дополнительную информацию можно найти в статье Плагин управления ключами AWS.

Версии

Версия Статус Введено
1.0 Стабильная MariaDB 10.2.6, MariaDB 10.1.24
1.0 Beta MariaDB 10.1.18
1.0 Экспериментальная MariaDB 10.1.13

example_key_management

Использует случайные ключи, генерируемые на основе времени, игнорирует идентификаторы ключей, поддерживает версии ключей и вращение ключей. Использует алгоритмы шифрования AES_ECB и AES_CBC и автоматически меняет их вместе с версиями ключей.

Версии

Версия Статус Введено
1.0 Экспериментальная MariaDB 10.1.3

debug_key_management

Ключ генерируется из версии, пользователь вручную управляет вращением ключа. Поддерживает только идентификатор ключа 1, использует только AES_CBC.

Версии

Версия Статус Введено
1.0 Экспериментальная MariaDB 10.1.3

Сервис шифрования

Шифрование, как правило, необходимо на самом низком уровне внутри движка хранения. То есть, движку хранения необходимо поддерживать шифрование и иметь доступ к функциям шифрования и управления ключами. Обычно плагин получает доступ к определенной функциональности на сервере через сервис. В данном случае сервер предоставляет сервис шифрования для использования движками хранения (и другими заинтересованными плагинами). Эти функции сервиса напрямую подключены к методам плагина шифрования (описанным выше).

Функции сервиса объявляются следующим образом:

unsigned int encryption_key_get_latest_version(unsigned int key_id);
unsigned int encryption_key_get(unsigned int key_id, unsigned int key_version,
                                unsigned char *buffer, unsigned int *length);
unsigned int encryption_ctx_size(unsigned int key_id, unsigned int key_version);
int encryption_ctx_init(void *ctx, const unsigned char *key, unsigned int klen,
                        const unsigned char *iv, unsigned int ivlen, int flags,
                        unsigned int key_id, unsigned int key_version);
int encryption_ctx_update(void *ctx, const unsigned char *src,
                          unsigned int slen, unsigned char *dst,
                          unsigned int *dlen);
int encryption_ctx_finish(void *ctx, unsigned char *dst, unsigned int *dlen);
unsigned int encryption_encrypted_length(unsigned int slen, unsigned int key_id,
                                         unsigned int key_version);

Также существуют вспомогательные функции для проверки существования ключа или версии ключа и для шифрования или расшифрования блока данных с помощью одного вызова функции.

unsigned int encryption_key_id_exists(unsigned int id);
unsigned int encryption_key_version_exists(unsigned int id,
                                           unsigned int version);
int encryption_crypt(const unsigned char *src, unsigned int slen,
                     unsigned char *dst, unsigned int *dlen,
                     const unsigned char *key, unsigned int klen,
                     const unsigned char *iv, unsigned int ivlen, int flags,
                     unsigned int key_id, unsigned int key_version);
Содержимое, воспроизведенное на этом сайте, является собственностью соответствующих владельцев, и это содержимое не предварительно проверяется компанией MariaDB. Мнения, информация и мнения, выраженные в этом содержании, не обязательно отражают точку зрения MariaDB или любой другой стороны.

© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/encryption-plugin-api/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API