Функции Шифрования
Эти функции реализуют шифрование и расшифровку данных с использованием алгоритма AES (Advanced Encryption Standard).
Длина ключа зависит от режима шифрования. Она составляет 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.
Запрос:
Результат:
Теперь давайте попробуем расшифровать все эти данные.
Запрос:
Результат:
Обратите внимание, что только часть данных была правильно расшифрована, а остальная часть — это бессмыслица, поскольку режим, ключ или вектор инициализации были разными при шифровании.
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:
Запрос:
Результат: