Перейти к основному содержанию
Перейти к основному содержанию

Функции шифрования

Эти функции реализуют шифрование и расшифрование данных с использованием алгоритма AES (Advanced Encryption Standard).

Длина ключа зависит от режима шифрования: 16, 24 и 32 байта для режимов -128-, -196- и -256- соответственно.

Длина вектора инициализации всегда составляет 16 байт (байты сверх 16 игнорируются).

HMAC

Добавлено в v25.12

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

Поддерживаемые алгоритмы хеширования:

  • RSA-MD4 (псевдонимы: MD4, RSA-MD4)
  • RSA-MD5 (псевдонимы: MD5, RSA-MD5)
  • RSA-MDC2 (псевдонимы: MDC2, RSA-MDC2)
  • RSA-RIPEMD160 (псевдонимы: RIPEMD160, RSA-RIPEMD160)
  • RSA-SHA1 (псевдонимы: RSA-SHA1, SHA1)
  • RSA-SHA1-2 (псевдонимы: RSA-SHA1, RSA-SHA1-2)
  • RSA-SHA224 (псевдонимы: RSA-SHA224, SHA224)
  • RSA-SHA256 (псевдонимы: RSA-SHA256, SHA256)
  • RSA-SHA3-224 (псевдонимы: RSA-SHA3-224, SHA3-224)
  • RSA-SHA3-256 (псевдонимы: RSA-SHA3-256, SHA3-256)
  • RSA-SHA3-384 (псевдонимы: RSA-SHA3-384, SHA3-384)
  • RSA-SHA3-512 (псевдонимы: RSA-SHA3-512, SHA3-512)
  • RSA-SHA384 (псевдонимы: RSA-SHA384, SHA384)
  • RSA-SHA512 (псевдонимы: RSA-SHA512, SHA512)
  • RSA-SHA512/224 (псевдонимы: RSA-SHA512/224, SHA512-224)
  • RSA-SHA512/256 (псевдонимы: RSA-SHA512/256, SHA512-256)
  • RSA-SM3 (псевдонимы: RSA-SM3, SM3)
  • blake2b512
  • blake2s256
  • id-rsassa-pkcs1-v1_5-with-sha3-224 (псевдонимы: SHA3-224, id-rsassa-pkcs1-v1_5-with-sha3-224)
  • id-rsassa-pkcs1-v1_5-with-sha3-256 (псевдонимы: SHA3-256, id-rsassa-pkcs1-v1_5-with-sha3-256)
  • id-rsassa-pkcs1-v1_5-with-sha3-384 (псевдонимы: SHA3-384, id-rsassa-pkcs1-v1_5-with-sha3-384)
  • id-rsassa-pkcs1-v1_5-with-sha3-512 (псевдонимы: SHA3-512, id-rsassa-pkcs1-v1_5-with-sha3-512)
  • md4
  • md4WithRSAEncryption (псевдонимы: MD4, md4WithRSAEncryption)
  • md5
  • md5-sha1
  • md5WithRSAEncryption (псевдонимы: MD5, md5WithRSAEncryption)
  • mdc2
  • mdc2WithRSA (псевдонимы: MDC2, mdc2WithRSA)
  • ripemd (псевдонимы: RIPEMD160, ripemd)
  • ripemd160
  • ripemd160WithRSA (псевдонимы: RIPEMD160, ripemd160WithRSA)
  • rmd160 (псевдонимы: RIPEMD160, rmd160)
  • sha1
  • sha1WithRSAEncryption (псевдонимы: SHA1, sha1WithRSAEncryption)
  • sha224
  • sha224WithRSAEncryption (псевдонимы: SHA224, sha224WithRSAEncryption)
  • sha256
  • sha256WithRSAEncryption (псевдонимы: SHA256, sha256WithRSAEncryption)
  • sha3-224
  • sha3-256
  • sha3-384
  • sha3-512
  • sha384
  • sha384WithRSAEncryption (псевдонимы: SHA384, sha384WithRSAEncryption)
  • sha512
  • sha512-224
  • sha512-224WithRSAEncryption (псевдонимы: SHA512-224, sha512-224WithRSAEncryption)
  • sha512-256
  • sha512-256WithRSAEncryption (псевдонимы: SHA512-256, sha512-256WithRSAEncryption)
  • sha512WithRSAEncryption (псевдонимы: SHA512, sha512WithRSAEncryption)
  • shake128
  • shake256
  • sm3
  • sm3WithRSAEncryption (псевдонимы: SM3, sm3WithRSAEncryption)
  • ssl3-md5 (псевдонимы: MD5, ssl3-md5)
  • ssl3-sha1 (псевдонимы: SHA1, ssl3-sha1)
  • whirlpool

Синтаксис

HMAC(mode, message, key)

Аргументы

  • mode — Имя алгоритма хеширования (регистронезависимое). Поддерживаются: md5, sha1, sha224, sha256, sha384, sha512. String
  • message — Сообщение, для которого вычисляется код аутентификации. String
  • key — Секретный ключ для HMAC. String

Возвращаемое значение

Возвращает бинарную строку, содержащую дайджест HMAC. String

Примеры

Простейший HMAC-SHA256

SELECT hex(HMAC('sha256', 'Быстрая коричневая лиса прыгает через ленивую собаку', 'secret_key'));
┌─hex(HMAC('sha256', 'The quick brown fox jumps over the lazy dog', 'secret_key'))─┐
│ 31FD15FA0F61FD40DC09D919D4AA5B4141A0B27C1D51E74A6789A890AAAA187C                 │
└──────────────────────────────────────────────────────────────────────────────────┘

Разные алгоритмы хеширования

SELECT
    hex(HMAC('md5', 'message', 'key')) AS hmac_md5,
    hex(HMAC('sha1', 'message', 'key')) AS hmac_sha1,
    hex(HMAC('sha256', 'message', 'key')) AS hmac_sha256;
┌─hmac_md5─────────────────────────┬─hmac_sha1────────────────────────────────┬─hmac_sha256──────────────────────────────────────────────────────┐
│ 4E4748E62B463521F6775FBF921234B5 │ 2088DF74D5F2146B48146CAF4965377E9D0BE3A4 │ 6E9EF29B75FFFC5B7ABAE527D58FDADB2FE42E7219011976917343065F58ED4A │
└──────────────────────────────────┴──────────────────────────────────────────┴──────────────────────────────────────────────────────────────────┘

Режим без учета регистра

SELECT
    hmac('SHA256', 'message', 'key') = HMAC('sha256', 'message', 'key') AS same_result,
    HMAC('SHA256', 'message', 'key') = Hmac('Sha256', 'message', 'key') AS also_same;
┌─same_result─┬─also_same─┐
│           1 │         1 │
└─────────────┴───────────┘

aes_decrypt_mysql

Появилась в версии v20.12

Расшифровывает данные, зашифрованные функцией MySQL AES_ENCRYPT.

Для одинаковых входных данных возвращает тот же открытый текст, что и decrypt. Если key или iv длиннее, чем должны быть, aes_decrypt_mysql ведет себя так же, как функция MySQL [aes_decrypt]: «сворачивает» key и игнорирует лишние биты iv.

Поддерживает следующие режимы расшифрования:

  • aes-128-ecb, aes-192-ecb, aes-256-ecb
  • aes-128-cbc, aes-192-cbc, aes-256-cbc
  • aes-128-cfb128
  • aes-128-ofb, aes-192-ofb, aes-256-ofb

Синтаксис

aes_decrypt_mysql(mode, ciphertext, key[, iv])

Аргументы

  • mode — режим расшифровки. String
  • ciphertext — зашифрованный текст, который нужно расшифровать. String
  • key — ключ расшифровки. String
  • iv — необязательный параметр. Вектор инициализации. String

Возвращаемое значение

Возвращает расшифрованное значение типа String. String

Примеры

Расшифровка данных MySQL

-- Расшифруем данные, которые мы ранее зашифровали с помощью MySQL:
mysql> SET  block_encryption_mode='aes-256-ofb';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT aes_encrypt('Secret', '123456789101213141516171819202122', 'iviviviviviviviv123456') as ciphertext;
+------------------------+
| ciphertext             |
+------------------------+
| 0x24E9E4966469         |
+------------------------+
1 строка в наборе (0.00 сек)

SELECT aes_decrypt_mysql('aes-256-ofb', unhex('24E9E4966469'), '123456789101213141516171819202122', 'iviviviviviviviv123456') AS plaintext
┌─plaintext─┐
│ Секрет    │
└───────────┘

aes_encrypt_mysql

Появилась в версии: v20.12

Шифрует текст тем же способом, что и функция MySQL AES_ENCRYPT. Полученный шифротекст может быть расшифрован функцией MySQL AES_DECRYPT. При тех же входных данных выдаёт тот же шифротекст, что и функция encrypt. Когда key или iv длиннее, чем обычно требуется, aes_encrypt_mysql ведёт себя так же, как MySQL aes_encrypt, то есть «сворачивает» key и игнорирует лишние биты iv.

Поддерживаемые режимы шифрования:

  • aes-128-ecb, aes-192-ecb, aes-256-ecb
  • aes-128-cbc, aes-192-cbc, aes-256-cbc
  • aes-128-ofb, aes-192-ofb, aes-256-ofb

Синтаксис

aes_encrypt_mysql(mode, plaintext, key[, iv])

Аргументы

  • mode — Режим шифрования. String
  • plaintext — Текст, подлежащий шифрованию. String
  • key — Ключ шифрования. Если ключ длиннее, чем требуется для mode, выполняется специфическая для MySQL свёртка ключа (key folding). String
  • iv — Необязательный параметр. Вектор инициализации. Учитываются только первые 16 байт. String

Возвращаемое значение

Бинарная строка зашифрованного текста. String

Примеры

Сравнение одинаковых входных данных

-- При одинаковых входных данных encrypt и aes_encrypt_mysql создают одинаковый шифротекст:
SELECT encrypt('aes-256-ofb', 'Secret', '12345678910121314151617181920212', 'iviviviviviviviv') = aes_encrypt_mysql('aes-256-ofb', 'Secret', '12345678910121314151617181920212', 'iviviviviviviviv') AS ciphertexts_equal;
┌─ciphertexts_equal─┐
│                 1 │
└───────────────────┘

Сбой Encrypt при слишком длинном ключе

-- Но encrypt завершается ошибкой, если ключ или iv длиннее ожидаемого:
SELECT encrypt('aes-256-ofb', 'Secret', '123456789101213141516171819202122', 'iviviviviviviviv123');
Получено исключение от сервера (версия 22.6.1):
Код: 36. DB::Exception: Получено от localhost:9000. DB::Exception: Недопустимый размер ключа: 33, ожидалось 32: При обработке encrypt('aes-256-ofb', 'Secret', '123456789101213141516171819202122', 'iviviviviviviviv123').

Совместимость с MySQL

-- aes_encrypt_mysql создаёт вывод, совместимый с MySQL:
SELECT hex(aes_encrypt_mysql('aes-256-ofb', 'Secret', '123456789101213141516171819202122', 'iviviviviviviviv123')) AS ciphertext;
┌─ciphertext───┐
│ 24E9E4966469 │
└──────────────┘

Более длинный IV приводит к тому же результату

-- Обратите внимание, что даже при использовании более длинного IV результат остается тем же
SELECT hex(aes_encrypt_mysql('aes-256-ofb', 'Secret', '123456789101213141516171819202122', 'iviviviviviviviv123456')) AS ciphertext
┌─ciphertext───┐
│ 24E9E4966469 │
└──────────────┘

decrypt

Впервые представлена в: v20.12

Эта функция расшифровывает двоичную строку, зашифрованную с помощью AES, с использованием следующих режимов:

  • aes-128-ecb, aes-192-ecb, aes-256-ecb
  • aes-128-cbc, aes-192-cbc, aes-256-cbc
  • aes-128-ofb, aes-192-ofb, aes-256-ofb
  • aes-128-gcm, aes-192-gcm, aes-256-gcm
  • aes-128-ctr, aes-192-ctr, aes-256-ctr
  • aes-128-cfb, aes-128-cfb1, aes-128-cfb8

Синтаксис

decrypt(mode, ciphertext, key[, iv, aad])

Аргументы

  • mode — режим расшифровки. String
  • ciphertext — зашифрованный текст, который необходимо расшифровать. String
  • key — ключ для расшифровки. String
  • iv — вектор инициализации. Обязателен для режимов -gcm, для остальных — необязателен. String
  • aad — дополнительные аутентифицированные данные. Расшифровка не произойдёт, если это значение неверно. Работает только в режимах -gcm, для остальных генерируется исключение. String

Возвращаемое значение

Возвращает расшифрованный открытый текст. String

Примеры

Правильная расшифровка зашифрованных данных

-- Повторно используем таблицу из примера функции encrypt
SELECT comment, hex(secret) FROM encryption_test;
┌─comment──────────────┬─hex(secret)──────────────────────────────────┐
│ aes-256-gcm          │ A8A3CCBC6426CFEEB60E4EAE03D3E94204C1B09E0254 │
│ aes-256-gcm с AAD    │ A8A3CCBC6426D9A1017A0A932322F1852260A4AD6837 │
└──────────────────────┴──────────────────────────────────────────────┘
┌─comment──────────────────────────┬─hex(secret)──────────────────────┐
│ aes-256-ofb без IV               │ B4972BDC4459                     │
│ aes-256-ofb без IV, другой ключ  │ 2FF57C092DC9                     │
│ aes-256-ofb с IV                 │ 5E6CB398F653                     │
│ aes-256-cbc без IV               │ 1BC0629A92450D9E73A00E7D02CF4142 │
└──────────────────────────────────┴──────────────────────────────────┘

Неверная расшифровка зашифрованных данных

SELECT comment, decrypt('aes-256-cfb128', secret, '12345678910121314151617181920212') AS plaintext FROM encryption_test
-- Обратите внимание, что корректно расшифрована только часть данных, а остальное представляет собой бессмысленный набор символов, так как при шифровании использовались другие значения `mode`, `key` или `iv`.
┌─comment──────────────┬─plaintext──┐
│ aes-256-gcm          │ OQ�E
                             �t�7T�\���\�   │
│ aes-256-gcm with AAD │ OQ�E
                             �\��si����;�o�� │
└──────────────────────┴────────────┘
┌─comment──────────────────────────┬─plaintext─┐
│ aes-256-ofb no IV                │ Secret    │
│ aes-256-ofb no IV, different key │ �4�
                                        �         │
│ aes-256-ofb with IV              │ ���6�~        │
│aes-256-cbc no IV                │ �2*4�h3c�4w��@
└──────────────────────────────────┴───────────┘

encrypt

Добавлена в версии: v20.12

Шифрует открытый текст в шифртекст с использованием AES в одном из следующих режимов:

  • aes-128-ecb, aes-192-ecb, aes-256-ecb
  • aes-128-cbc, aes-192-cbc, aes-256-cbc
  • aes-128-ofb, aes-192-ofb, aes-256-ofb
  • aes-128-gcm, aes-192-gcm, aes-256-gcm
  • aes-128-ctr, aes-192-ctr, aes-256-ctr
  • aes-128-cfb, aes-128-cfb1, aes-128-cfb8

Синтаксис

encrypt(mode, plaintext, key[, iv, aad])

Аргументы

  • mode — режим шифрования. String
  • plaintext — текст, который нужно зашифровать. String
  • key — ключ шифрования. String
  • iv — вектор инициализации. Обязателен для режимов -gcm, для остальных — необязателен. String
  • aad — дополнительные аутентифицированные данные. Они не шифруются, но влияют на расшифровку. Работает только в режимах -gcm, для остальных генерируется исключение. String

Возвращаемое значение

Возвращает бинарную строку с зашифрованными данными (ciphertext). String

Примеры

Пример шифрования

CREATE TABLE encryption_test
(
    `comment` String,
    `secret` String
)
ENGINE = MergeTree;

INSERT INTO encryption_test VALUES
('aes-256-ofb без IV', encrypt('aes-256-ofb', 'Secret', '12345678910121314151617181920212')),
('aes-256-ofb без IV, другой ключ', encrypt('aes-256-ofb', 'Secret', 'keykeykeykeykeykeykeykeykeykeyke')),
('aes-256-ofb с IV', encrypt('aes-256-ofb', 'Secret', '12345678910121314151617181920212', 'iviviviviviviviv')),
('aes-256-cbc без IV', encrypt('aes-256-cbc', 'Secret', '12345678910121314151617181920212'));

SELECT comment, hex(secret) FROM encryption_test;
┌─comment──────────────────────────┬─hex(secret)──────────────────────┐
│ aes-256-ofb без IV                │ B4972BDC4459                     │
│ aes-256-ofb без IV, другой ключ │ 2FF57C092DC9                     │
│ aes-256-ofb с IV              │ 5E6CB398F653                     │
│ aes-256-cbc без IV                │ 1BC0629A92450D9E73A00E7D02CF4142 │
└──────────────────────────────────┴──────────────────────────────────┘

Пример для режима GCM

INSERT INTO encryption_test VALUES
('aes-256-gcm', encrypt('aes-256-gcm', 'Secret', '12345678910121314151617181920212', 'iviviviviviviviv')),

('aes-256-gcm with AAD', encrypt('aes-256-gcm', 'Secret', '12345678910121314151617181920212', 'iviviviviviviviv', 'aad'));

SELECT comment, hex(secret) FROM encryption_test WHERE comment LIKE '%gcm%';
┌─comment──────────────┬─hex(secret)──────────────────────────────────┐
│ aes-256-gcm          │ A8A3CCBC6426CFEEB60E4EAE03D3E94204C1B09E0254 │
│ aes-256-gcm with AAD │ A8A3CCBC6426D9A1017A0A932322F1852260A4AD6837 │
└──────────────────────┴──────────────────────────────────────────────┘

tryDecrypt

Добавлена в: v22.10

Аналогична функции decrypt, но возвращает NULL, если расшифровка не удалась при использовании неправильного ключа.

Синтаксис

tryDecrypt(mode, ciphertext, key[, iv, aad])

Аргументы

  • mode — Режим расшифровки. String
  • ciphertext — Зашифрованный текст, который нужно расшифровать. String
  • key — Ключ для расшифровки. String
  • iv — Необязательный параметр. Вектор инициализации. Обязателен для режимов -gcm, необязателен для остальных режимов. String
  • aad — Необязательный параметр. Дополнительные аутентифицируемые данные. Расшифровка не будет выполнена, если это значение неверно. Работает только в режимах -gcm, для других режимов выбрасывается исключение. String

Возвращаемое значение

Возвращает расшифрованный String или NULL, если расшифровка не удалась. Nullable(String)

Примеры

Создание таблицы и вставка данных

-- Создадим таблицу, где user_id — уникальный идентификатор пользователя, encrypted — зашифрованное строковое поле, iv — вектор инициализации для расшифровки/шифрования.
-- Предполагается, что пользователи знают свой идентификатор и ключ для расшифровки зашифрованного поля:
CREATE TABLE decrypt_null
(
    dt DateTime,
    user_id UInt32,
    encrypted String,
    iv String
)
ENGINE = MergeTree;

-- Вставим данные:
INSERT INTO decrypt_null VALUES
('2022-08-02 00:00:00', 1, encrypt('aes-256-gcm', 'value1', 'keykeykeykeykeykeykeykeykeykey01', 'iv1'), 'iv1'),
('2022-09-02 00:00:00', 2, encrypt('aes-256-gcm', 'value2', 'keykeykeykeykeykeykeykeykeykey02', 'iv2'), 'iv2'),
('2022-09-02 00:00:01', 3, encrypt('aes-256-gcm', 'value3', 'keykeykeykeykeykeykeykeykeykey03', 'iv3'), 'iv3');

-- Попробуем расшифровать с помощью одного ключа
SELECT
    dt,
    user_id,
    tryDecrypt('aes-256-gcm', encrypted, 'keykeykeykeykeykeykeykeykeykey02', iv) AS value
FROM decrypt_null
ORDER BY user_id ASC
┌──────────────────dt─┬─user_id─┬─value──┐
│ 2022-08-02 00:00:00 │       1 │ ᴺᵁᴸᴸ   │
│ 2022-09-02 00:00:00 │       2 │ value2 │
│ 2022-09-02 00:00:01 │       3 │ ᴺᵁᴸᴸ   │
└─────────────────────┴─────────┴────────┘