Функции шифрования
Эти функции осуществляют шифрование и расшифровку данных с использованием алгоритма AES (Расширенный стандарт шифрования).
Длина ключа зависит от режима шифрования. Она составляет 16, 24 и 32 байта для режимов -128-
, -196-
и -256-
соответственно.
Длина вектора инициализации всегда составляет 16 байт (байты, превышающие 16, игнорируются).
Обратите внимание, что эти функции работают медленно до ClickHouse 21.1.
encrypt
Эта функция шифрует данные, используя следующие режимы:
- 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
Синтаксис
Аргументы
mode
— Режим шифрования. String.plaintext
— Текст, который нужно зашифровать. String.key
— Ключ шифрования. String.iv
— Вектор инициализации. Обязателен для режимов-gcm
, необязателен для остальных. String.aad
— Дополнительные аутентифицированные данные. Он не шифруется, но влияет на расшифровку. Работает только в режимах-gcm
, для остальных выдаст исключение. String.
Возвращаемое значение
- Бинарная строка шифротекста. String.
Примеры
Создайте эту таблицу:
Запрос:
Вставьте некоторые данные (пожалуйста, избегайте хранения ключей/iv в базе данных, так как это подрывает всю концепцию шифрования), также хранение 'подсказок' небезопасно и используется только в иллюстративных целях:
Запрос:
Запрос:
Результат:
Пример с -gcm
:
Запрос:
Результат:
aes_encrypt_mysql
Совместим с шифрованием MySQL и полученный шифротекст может быть расшифрован с помощью функции AES_DECRYPT.
Производит тот же шифротекст, что и 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
Синтаксис
Аргументы
mode
— Режим шифрования. String.plaintext
— Текст, который нужно зашифровать. String.key
— Ключ шифрования. Если ключ длиннее, чем требуется для режима, выполняется специфическая для MySQL сворачивание ключа. String.iv
— Вектор инициализации. Необязательный, учитываются только первые 16 байт String.
Возвращаемое значение
- Бинарная строка шифротекста. String.
Примеры
При равных входных данных encrypt
и aes_encrypt_mysql
производят один и тот же шифротекст:
Запрос:
Результат:
Но encrypt
завершает работу с ошибкой, когда key
или iv
длиннее, чем ожидается:
Запрос:
Результат:
В то время как aes_encrypt_mysql
производит выход, совместимый с MySQL:
Запрос:
Результат:
Обратите внимание, что даже предоставление более длинного IV
производит тот же результат.
Запрос:
Результат:
Что является бинарно равным тому, что MySQL производит при тех же входных данных:
decrypt
Эта функция расшифровывает шифротекст в открытый текст, используя следующие режимы:
- 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
Синтаксис
Аргументы
mode
— Режим расшифровки. String.ciphertext
— Зашифрованный текст, который необходимо расшифровать. String.key
— Ключ расшифровки. String.iv
— Вектор инициализации. Обязателен для режимов-gcm
, необязателен для других. String.aad
— Дополнительные аутентифицированные данные. Не будет расшифрован, если это значение неверно. Работает только в режимах-gcm
, для остальных выдает исключение. String.
Возвращаемое значение
- Расшифрованная строка. String.
Примеры
Повторно используем таблицу из encrypt.
Запрос:
Результат:
Теперь давайте попробуем расшифровать все эти данные.
Запрос:
Результат:
Обратите внимание, что только часть данных была правильно расшифрована, а остальное является бессмысленным текстом, потому что либо mode
, key
, либо iv
были различны при шифровании.
tryDecrypt
Похожа на decrypt
, но возвращает NULL, если расшифровка завершилась неудачей из-за использования неверного ключа.
Примеры
Создадим таблицу, где user_id
— это уникальный идентификатор пользователя, encrypted
— это зашифрованное строковое поле, iv
— начальный вектор для расшифровки/шифрования. Предположим, что пользователи знают свой идентификатор и ключ для расшифровки зашифрованного поля:
Вставьте данные:
Запрос:
Результат:
aes_decrypt_mysql
Совместим с шифрованием MySQL и расшифровывает данные, зашифрованные с помощью функции AES_ENCRYPT.
Производит тот же открытый текст, что и decrypt
при равных входных данных. Но когда key
или iv
длиннее, чем должно быть, aes_decrypt_mysql
действует так же, как и aes_decrypt
в MySQL: 'сворачивает' 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
Синтаксис
Аргументы
mode
— Режим расшифровки. String.ciphertext
— Зашифрованный текст, который нужно расшифровать. String.key
— Ключ расшифровки. String.iv
— Вектор инициализации. Необязательный. String.
Возвращаемое значение
- Расшифрованная строка. String.
Примеры
Давайте расшифруем данные, которые мы ранее зашифровали с помощью MySQL:
Запрос:
Результат: