AEAD 加密概念

GoogleSQL for BigQuery 支持 AEAD 加密。

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

AEAD 加密的用途

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

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

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

密钥集

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

密钥集在 GoogleSQL 中采用 BYTES 形式的序列化 google.crypto.tink.Keyset 协议缓冲区表示法。

示例

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

{
  "primaryKeyId": 569259624,
  "key": [
    {
      "keyData": {
        "typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
        "value": "GiDPhTp5gIhfnDb6jfKOT4SmNoriIJc7ah8uRvrCpdNihA==",
        "keyMaterialType": "SYMMETRIC"
      },
      "status": "ENABLED",
      "keyId": 569259624,
      "outputPrefixType": "TINK"
    },
    {
      "keyData": {
        "typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
        "value": "GiBp6aU2cFbVfTh9dTQ1F0fqM+sGHXc56RDPryjAnzTe2A==",
        "keyMaterialType": "SYMMETRIC"
      },
      "status": "DISABLED",
      "keyId": 852264701,
      "outputPrefixType": "TINK"
    },
    {
      "status": "DESTROYED",
      "keyId": 237910588,
      "outputPrefixType": "TINK"
    }
  ]
}

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

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

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

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

封装的密钥集

如果您需要安全地管理密钥集或通过不受信任的渠道进行传输,请考虑使用封装的密钥集。封装原始密钥集时,此过程会使用 Cloud KMS 密钥加密原始密钥集。

封装的密钥集可以加密和解密数据,而不会泄露密钥集数据。虽然还有其他方法可以限制对字段级数据的访问,但与原始密钥集相比,封装的密钥集为密钥集管理提供了更安全的机制。

密钥集一样,封装的密钥集可以也应该定期轮替。封装的密钥集用于 AEAD 信封加密函数

下面是与封装密钥集有关的一些函数示例:

高级加密标准 (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 个字节的初始化矢量作为初始块,并将此初始块与第一个明文块进行异或运算。

CBC 模式不是加密意义上的 AEAD 方案,因为它不提供数据完整性;换句话说,对加密数据的恶意修改不会被检测,这些恶意修改也会破坏数据机密性。因此,除非需要旧版,否则不建议使用 CBC。

附加数据

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_KEYSETKEYS.ROTATE_WRAPPED_KEYSET 函数执行第一步操作,方法是向密钥集添加新的主加密密钥,并将旧的主加密密钥变成辅助加密密钥。

Cloud KMS 密钥

GoogleSQL 支持将 AEAD 加密函数Cloud KMS 密钥搭配使用,以进一步保护您的数据。这一额外的保护层使用密钥加密密钥 (KEK) 加密您的数据加密密钥 (DEK)。KEK 是对称加密密钥集,安全存储在 Cloud Key Management Service 中,并使用 Cloud KMS 权限和角色进行管理。

在查询执行时,请使用 KEYS.KEYSET_CHAIN 函数提供 KEK 的 KMS 资源路径以及封装的 DEK 中的密文。BigQuery 调用 Cloud KMS 对 DEK 进行解封装,然后使用该密钥对查询中的数据进行解密。解封装后的 DEK 版本仅在查询期间存储在内存中,然后进行销毁。

如需了解详情,请参阅使用 Cloud KMS 密钥进行 SQL 列级加密