加密函数
这些函数使用 AES (高级加密标准) 算法实现数据的加密和解密。
密钥长度取决于加密模式。对于 -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。
示例
创建此表:
查询:
插入一些数据(请避免将密钥/iv 存储在数据库中,因为这会破坏加密的整个概念);同时存储“提示”也不安全,仅用于说明目的:
查询:
查询:
结果:
使用 -gcm
的示例:
查询:
结果:
aes_encrypt_mysql
与 mysql 加密兼容,结果密文可用 AES_DECRYPT 函数解密。
在相同输入下将生成与 encrypt
相同的密文。但是当 key
或 iv
超过正常长度时,aes_encrypt_mysql
将遵循 MySQL 的 aes_encrypt
所做的:'折叠' 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
生成相同的密文:
查询:
结果:
但是当 key
或 iv
超过预期时,encrypt
会失败:
查询:
结果:
而 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
是唯一的用户 ID,encrypted
是加密字符串字段,iv
是解密/加密的初始向量。假设用户知道他们的 ID 和解密加密字段的密钥:
插入一些数据:
查询:
结果:
aes_decrypt_mysql
与 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
语法
参数
返回值
- 解密字符串。 String。
示例
让我们解密之前用 MySQL 加密的数据:
查询:
结果: