Функции Шифрования
Эти функции реализуют шифрование и расшифровку данных с использованием алгоритма AES (Advanced Encryption Standard).
Длина ключа зависит от режима шифрования. Для режимов -128-
, -196-
и -256-
она составляет 16, 24 и 32 байта соответственно.
Длина вектора инициализации всегда составляет 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.
Примеры
Создайте эту таблицу:
Запрос:
Вставьте некоторые данные (пожалуйста, избегайте хранения ключей/векторов инициализации в базе данных, так как это подрывает всю концепцию шифрования), также хранение 'подсказок' небезопасно и используется только в иллюстративных целях:
Запрос:
Запрос:
Результат:
Пример с -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:
Запрос:
Результат: