Функции шифрования
Эти функции осуществляют шифрование и расшифровку данных с использованием алгоритма 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:
Запрос:
Результат: