跳到主要内容
跳到主要内容

加密函数

这些函数使用 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 相同的密文。但是,当 keyiv 长度大于预期时,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.

示例

对于相同输入,encryptaes_encrypt_mysql 产生相同的密文:

查询:

结果:

但是,当 keyiv 长于预期时,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 的表。

查询:

结果:

现在让我们尝试解密所有数据。

查询:

结果:

注意,只有一部分数据被正确解密,其余则是乱码,因为在加密时 modekeyiv 不同。

tryDecrypt

decrypt 类似,但如果因使用了错误的密钥而导致解密失败,则返回 NULL。

示例

我们创建一个表,其中 user_id 是唯一用户 ID,encrypted 是加密字符串字段,iv 是用于解密/加密的初始向量。假设用户知道他们的 ID 及其解密字段的密钥:

插入一些数据:

查询:

结果:

aes_decrypt_mysql

与 MySQL 加密兼容,解密使用 AES_ENCRYPT 函数加密的数据。

在相同输入下,将生成与 decrypt 相同的明文。但是,当 keyiv 长度超过正常长度时,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

语法

参数

  • mode — 解密模式。 String.
  • ciphertext — 需要解密的加密文本。 String.
  • key — 解密密钥。 String.
  • iv — 初始化向量。可选。 String.

返回值

  • 解密后的字符串。 String.

示例

让我们解密之前使用 MySQL 加密的数据:

查询:

结果: