Эти функции реализуют шифрование и дешифрование данных с помощью алгоритма AES (Advanced Encryption Standard).
Длина ключа зависит от режима шифрования: 16, 24 и 32 байта для режимов -128-, -196- и -256- соответственно.
Длина вектора инициализации всегда составляет 16 байт (байты сверх этого значения игнорируются).
HMAC
Добавленный в: v25.12.0
Вычисляет HMAC (Hash-based Message Authentication Code) для указанного сообщения с использованием заданного алгоритма хеширования и секретного ключа.
Поддерживаемые алгоритмы хеширования:
- blake2b512
- blake2s256
- md4
- md5
- md5-sha1
- mdc2
- ripemd (псевдонимы: RIPEMD160, ripemd)
- ripemd160
- rmd160 (псевдонимы: RIPEMD160, rmd160)
- sha1
- sha224
- sha256
- sha3-224
- sha3-256
- sha3-384
- sha3-512
- sha384
- sha512
- sha512-224
- sha512-256
- shake128
- shake256
- sm3
- ssl3-md5 (псевдонимы: MD5, ssl3-md5)
- ssl3-sha1 (псевдонимы: SHA1, ssl3-sha1)
- whirlpool
Синтаксис
HMAC(mode, message, key)Аргументы
mode— Имя алгоритма хеширования (регистронезависимо). Поддерживаются: md5, sha1, sha224, sha256, sha384, sha512.Stringmessage— Сообщение, подлежащее аутентификации.Stringkey— Секретный ключ для HMAC.String
Возвращаемое значение
Возвращает двоичную строку с дайджестом HMAC. String
Примеры
Базовый HMAC-SHA256
SELECT hex(HMAC('sha256', 'The quick brown fox jumps over the lazy dog', 'secret_key'));┌─hex(HMAC('sha256', 'The quick brown fox jumps over the lazy dog', [HIDDEN id: 1]))─┐
│ 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.0
Расшифровывает данные, зашифрованные функцией 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— Режим расшифровки.Stringciphertext— Шифротекст, который нужно расшифровать.Stringkey— Ключ для расшифровки.Stringiv— Необязательно. Вектор инициализации.String
Возвращаемое значение
Возвращает расшифрованную строку. String
Примеры
Расшифровка данных MySQL
-- Let's decrypt data we've previously encrypted with 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 row in set (0.00 sec)
SELECT aes_decrypt_mysql('aes-256-ofb', unhex('24E9E4966469'), '123456789101213141516171819202122', 'iviviviviviviviv123456') AS plaintext┌─plaintext─┐
│ Secret │
└───────────┘aes_encrypt_mysql
Добавленный в: v20.12.0
Шифрует текст так же, как функция AES_ENCRYPT в MySQL.
Полученный шифротекст можно расшифровать с помощью функции AES_DECRYPT в MySQL.
Для одинаковых входных данных возвращает тот же шифротекст, что и функция encrypt.
Если key или iv длиннее, чем требуется, aes_encrypt_mysql будет следовать поведению aes_encrypt в MySQL: 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— Режим шифрования.Stringplaintext— Открытый текст, который нужно зашифровать.Stringkey— Ключ шифрования. Если ключ длиннее, чем требуется дляmode, выполняется специфическое для MySQL свёртывание ключа.Stringiv— Необязательно. Вектор инициализации. Учитываются только первые 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 завершается ошибкой, если key или iv длиннее ожидаемого:
SELECT encrypt('aes-256-ofb', 'Secret', '123456789101213141516171819202122', 'iviviviviviviviv123');Received exception from server (version 22.6.1):
Code: 36. DB::Exception: Received from localhost:9000. DB::Exception: Invalid key size: 33 expected 32: While processing 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.0
Эта функция расшифровывает двоичную строку, зашифрованную алгоритмом 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— Режим расшифровки.Stringciphertext— Шифротекст, который требуется расшифровать.Stringkey— Ключ для расшифровки.Stringiv— Вектор инициализации. Обязателен для режимов-gcm, в остальных случаях — необязателен.Stringaad— Дополнительные аутентифицированные данные. Если это значение неверно, расшифровка не выполнится. Работает только в режимах-gcm; в остальных случаях генерирует исключение.String
Возвращаемое значение
Возвращает расшифрованный открытый текст. String
Примеры
Корректная расшифровка зашифрованных данных
CREATE TABLE encryption_test
(
`comment` String,
`secret` String
)
ENGINE = MergeTree
ORDER BY tuple();
INSERT INTO encryption_test VALUES
('aes-256-ofb no IV', encrypt('aes-256-ofb', 'Secret', '12345678910121314151617181920212')),
('aes-256-ofb no IV, different key', encrypt('aes-256-ofb', 'Secret', 'keykeykeykeykeykeykeykeykeykeyke')),
('aes-256-ofb with IV', encrypt('aes-256-ofb', 'Secret', '12345678910121314151617181920212', 'iviviviviviviviv')),
('aes-256-cbc no IV', encrypt('aes-256-cbc', 'Secret', '12345678910121314151617181920212'));
SELECT comment, hex(secret) FROM encryption_test;┌─comment──────────────────────────┬─hex(secret)──────────────────────┐
│ aes-256-ofb no IV │ B4972BDC4459 │
│ aes-256-ofb no IV, different key │ 2FF57C092DC9 │
│ aes-256-ofb with IV │ 5E6CB398F653 │
│ aes-256-cbc no IV │ 1BC0629A92450D9E73A00E7D02CF4142 │
└──────────────────────────────────┴──────────────────────────────────┘Неправильная расшифровка зашифрованных данных
SELECT comment, hex(decrypt('aes-256-cfb8', secret, '12345678910121314151617181920212')) AS plaintext FROM encryption_testaes-256-ofb no IV 53A69A28E815
aes-256-ofb no IV, different key C86BD2404D8A
aes-256-ofb with IV B9658159142A
aes-256-cbc no IV FC552E5096F1455997B2732FB31DCFEBencrypt
Добавленный в: v20.12.0
Шифрует открытый текст в шифротекст с помощью 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— Режим шифрования.Stringplaintext— Открытый текст, который нужно зашифровать.Stringkey— Ключ шифрования.Stringiv— Вектор инициализации. Обязателен для режимов-gcm, для остальных — необязателен.Stringaad— Дополнительные аутентифицированные данные. Эти данные не шифруются, но влияют на расшифровку. Работает только в режимах-gcm, в остальных режимах генерируется исключение.String
Возвращаемое значение
Возвращает шифртекст в виде двоичной строки. String
Примеры
Пример шифрования
CREATE TABLE encryption_test
(
`comment` String,
`secret` String
)
ENGINE = MergeTree;
INSERT INTO encryption_test VALUES
('aes-256-ofb no IV', encrypt('aes-256-ofb', 'Secret', '12345678910121314151617181920212')),
('aes-256-ofb no IV, different key', encrypt('aes-256-ofb', 'Secret', 'keykeykeykeykeykeykeykeykeykeyke')),
('aes-256-ofb with IV', encrypt('aes-256-ofb', 'Secret', '12345678910121314151617181920212', 'iviviviviviviviv')),
('aes-256-cbc no IV', encrypt('aes-256-cbc', 'Secret', '12345678910121314151617181920212'));
SELECT comment, hex(secret) FROM encryption_test;┌─comment──────────────────────────┬─hex(secret)──────────────────────┐
│ aes-256-ofb no IV │ B4972BDC4459 │
│ aes-256-ofb no IV, different key │ 2FF57C092DC9 │
│ aes-256-ofb with IV │ 5E6CB398F653 │
│ aes-256-cbc no 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.0
Аналогично функции decrypt, но возвращает NULL, если при использовании неверного ключа расшифровать данные не удаётся.
Синтаксис
tryDecrypt(mode, ciphertext, key[, iv, aad])Аргументы
mode— Режим расшифровки.Stringciphertext— Шифротекст, который нужно расшифровать.Stringkey— Ключ расшифровки.Stringiv— Необязательно. Вектор инициализации. Обязателен для режимов-gcm, для остальных режимов необязателен.Stringaad— Необязательно. Дополнительные аутентифицированные данные. Если это значение неверно, расшифровка не выполнится. Работает только в режимах-gcm; для остальных режимов генерирует исключение.String
Возвращаемое значение
Возвращает расшифрованную строку или NULL, если расшифровка не удалась. Nullable(String)
Примеры
Создание таблицы и вставка данных
-- Создадим таблицу, где user_id — уникальный идентификатор пользователя, encrypted — зашифрованное строковое поле, iv — начальный вектор для расшифровки/шифрования.
-- Предполагается, что пользователи знают свой id и ключ для расшифровки поля encrypted:
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 │ ᴺᵁᴸᴸ │
└─────────────────────┴─────────┴────────┘