标准 SQL 中的 AEAD 加密概念

本主题说明了 BigQuery 中 AEAD 加密背后的概念。如需了解 BigQuery 支持的各种 AEAD 加密函数,请参阅 AEAD 加密函数

AEAD 加密的用途

BigQuery 使用静态数据加密来确保您数据的安全。BigQuery 还支持客户管理的加密密钥 (CMEK),可让您使用特定加密密钥对表进行加密。但是,在某些情况下,您可能希望对表中的个别值进行加密。

例如,您希望将自己的所有客户数据都保存在一个公用表中,并使用不同的密钥来加密每个客户的数据。若您有数据分布在多个表中,可能会希望能够对这些表执行“密钥删除”。“密钥删除”(或称“密钥销毁”)是一个删除加密密钥以显示使用该密钥加密的任何不可读数据的过程。

AEAD 加密函数可让您创建包含加密和解密密钥的密钥集、使用这些密钥对表中的个别值进行加密和解密,以及轮替密钥集内的密钥。

密钥集

密钥集是一组加密密钥,由一个主加密密钥和其余的辅助加密密钥(如果有的话)组成。无论是启用的、停用的还是已销毁的密钥,每个密钥都是对一个加密或解密算法的编码。对于非销毁密钥,则是对自身的字节编码。主加密密钥决定了输入明文的加密方式。主加密密钥永不可停用。辅助加密密钥只能用于解密,可以将其启用或停用。密钥集可用于解密使用该密钥集加密的任何数据。

密钥集在 BigQuery 中采用 BYTES 形式的序列化 google.crypto.tink.Keyset Protocol Buffer 表示法。

示例

以下是 AEAD 密钥集的示例,以 JSON 字符串表示,包含三个密钥。

primary_key_id: 569259624
key {
  key_data {
    type_url: "type.googleapis.com/google.crypto.tink.AesGcmKey"
    value: ",&\264kh\377\306\217\371\233E<\0350A4\023B-pd\203\277\240\371\212^\210bf\347\256"
    key_material_type: SYMMETRIC
  }
  status: ENABLED
  key_id: 569259624
  output_prefix_type: TINK
}
key {
  key_data {
    type_url: "type.googleapis.com/google.crypto.tink.AesGcmKey"
    value: "\374\336+.\333\245k\364\010`\037\267!\376\233\\3\215\020\356B\236\240O\256U\021\266\217\277\217\271"
    key_material_type: SYMMETRIC
  }
  status: DISABLED
  key_id: 852264701
  output_prefix_type: TINK
}
key {
  status: DESTROYED
  key_id: 237910588
  output_prefix_type: TINK
}

在上面的示例中,主加密密钥的 ID 为 569259624,是 JSON 字符串中列出的第一个密钥。有两个辅助加密密钥:ID 为 852264701 的密钥处于停用状态,另一个 ID 为 237910588 的密钥处于已销毁状态。当 AEAD 加密函数使用此密钥集进行加密时,生成的密文会对主加密密钥 ID 569259624 进行编码。

当 AEAD 函数使用此密钥集进行解密时,该函数会根据密文中编码的密钥 ID 选择适当的密钥进行解密。在上例中,尝试使用密钥 ID 852264701237910588 进行解密将会导致出错,因为密钥 ID 852264701 为已停用且 ID 237910588 为已销毁。将密钥 ID 852264701 恢复为启用状态后,才可用于解密。

密钥类型用于确定与该密钥搭配使用的加密模式

由于使用 OpenSSL 提供的伪随机数生成器选择的初始化矢量 (IV) 各不相同,因此若使用同一密钥集对明文进行多次加密,通常每次返回的密文值都不相同。

高级加密标准 (AES)

AEAD 加密函数使用高级加密标准 (AES) 加密。AES 加密接受明文和加密密钥作为输入,并会返回加密的字节序列作为输出。随后,便可使用加密时所用的同一密钥来解密此字节序列。AES 使用的块大小为 16 个字节,这意味着明文会被视为一组 16 个字节的块序列。密文将包含 Tink 特定的前缀,以指示用于执行加密的密钥。AES 加密支持多种块加密模式

块加密模式

AEAD 加密函数支持两种块加密模式:GCM 和 CBC。

GCM

伽罗瓦/计数器模式 (GCM) 是一种适用于 AES 加密的模式。该函数按顺序对块进行编号,然后将此块编号与初始化矢量 (IV) 组合在一起。初始化矢量是一个随机值或伪随机值,是对明文数据进行随机化处理的基础。接下来,该函数会使用 AES 对块编号和 IV 的组合进行加密。然后,会对加密结果和明文执行按位逻辑异或 (XOR) 运算以生成密文。GCM 模式使用 128 或 256 位的加密密钥。

CBC 模式

在 CBC 模式中,通过将每个明文块与前一个密文块进行异或运算将各个块“链接”在一起,然后再进行加密。CBC 模式使用 128 位、192 位或 256 位的加密密钥。CBC 使用一个 16 个字节的初始化矢量作为初始块,并将此初始块与第一个明文块进行异或运算。

附加数据

AEAD 加密函数支持使用 additional_data 参数,该参数也称为关联数据 (AD) 或附加身份验证数据。与密钥集不同,此附加数据本身无法解密其生成的密文。此附加数据可保证加密数据的真实性和完整性,但不保证其保密性。

例如,在为特定客户加密数据时,additional_data 可以作为 CAST(customer_id AS STRING) 的输出。这可确保在解密数据时,数据先前已使用预期的 customer_id 进行加密。解密时需要使用相同的 additional_data 值。如需了解详情,请参阅 RFC 5116

解密

AEAD.ENCRYPT 的输出是密文 BYTESAEAD.DECRYPT_STRINGAEAD.DECRYPT_BYTES 函数可以对此密文进行解密。这些函数必须使用包含加密所用密钥的密钥集。密钥必须处于 'ENABLED' 状态。这些函数还必须使用加密时所使用的相同 additional_data

当使用密钥集进行解密时,系统会根据密文中编码的密钥 ID 选择相应的密钥进行解密。

AEAD.DECRYPT_STRING 的输出是明文 STRING,而 AEAD.DECRYPT_BYTES 的输出是明文 BYTESAEAD.DECRYPT_STRING 可以解密对 STRING 值进行编码的密文;AEAD.DECRYPT_BYTES 可以解密对 BYTES 值进行编码的密文。使用其中一个函数来解密对错误数据类型进行编码的密文(例如,使用 AEAD.DECRYPT_STRING 来解密对 BYTES 值进行编码的密文)会导致不确定的行为,并且可能会导致错误。

密钥轮替

轮替加密密钥主要是为了减少使用任何特定密钥加密数据的数据量,这样一来,即使某个密钥被破解,攻击者也只能访问到较少的数据。

密钥集轮替涉及以下操作:

  1. 在每个密钥集内创建新的主加密密钥。
  2. 对所有已加密数据进行解密,然后再重新加密。

KEYS.ROTATE_KEYSET 函数执行第一步操作,方法是向密钥集添加新的主加密密钥,并将旧的主加密密钥变成辅助加密密钥。

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
需要帮助?请访问我们的支持页面