标准 SQL 中的 AEAD 加密函数

以下部分介绍了 BigQuery 支持的 AEAD 加密函数。如需了解 AEAD 加密函数的工作原理,请参阅 AEAD 加密概念

KEYS.NEW_KEYSET

KEYS.NEW_KEYSET(key_type)

说明

返回一个序列化密钥集,其中包含基于 key_type 的新密钥。返回的密钥集是序列化 BYTES 形式的 google.crypto.tink.Keyset,其中包含一个主要加密密钥,不包含其他密钥。您可以将该密钥集与 AEAD.ENCRYPTAEAD.DECRYPT_BYTESAEAD.DECRYPT_STRING 函数结合使用来进行加密和解密,也可与密钥相关函数和密钥集相关函数的 KEYS 组结合使用。

key_typeSTRING 字面量形式的要创建的密钥类型。key_type 不能为 NULL。对于 key_type,当前唯一支持的值是 AEAD_AES_GCM_256KEYS.NEW_KEYSET(AEAD_AES_GCM_256) 使用 OpenSSL 提供的伪随机数生成器创建一个 256 位密钥。该密钥将使用 AES-GCM 进行加密和解密操作。

返回数据类型

BYTES

示例

以下查询会为 CustomerIds 中的每一行创建一个密钥集,随后该密钥集可用于加密数据。每个密钥集包含单个加密密钥与随机生成的密钥数据。输出中的每一行包含一个 customer_id 和一个 BYTES 形式的 'AEAD_AES_GCM_256' 密钥。

SELECT customer_id, KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset
FROM (
  SELECT 1 AS customer_id UNION ALL
  SELECT 2 UNION ALL
  SELECT 3
) AS CustomerIds;

KEYS.ADD_KEY_FROM_RAW_BYTES

KEYS.ADD_KEY_FROM_RAW_BYTES(keyset, key_type, raw_key_bytes)

说明

返回一个 BYTES 形式的序列化密钥集,并基于 key_typeraw_key_byteskeyset 添加密钥。

主要加密密钥仍与 keyset 中相同。raw_key_bytes 的预期长度取决于 key_type 的值。以下是受支持的 key_types

  • 'AES_CBC_PKCS':使用密码分组链接和 PKCS 填充为 AES 解密创建密钥。raw_key_bytes 应是长度为 16、24 或 32 的原始密钥 BYTES 值;这些长度的大小分别为 128、192 和 256 位。BigQuery AEAD 函数不支持使用这些类型的密钥进行加密;相反, 'AEAD_AES_GCM_256''AES_GCM' 是首选的密钥类型。

  • 'AES_GCM':采用伽罗瓦/计数器模式创建 AES 解密或加密密钥。 raw_key_bytes 必须是长度为 16 或 32 的原始密钥 BYTES 值;这些长度的大小分别为 128 和 256 位。当此类型密钥是 AEAD.ENCRYPT 的输入时,输出密文不包含指示输入密钥的特定于 Tink 的前缀。

返回数据类型

BYTES

示例

以下查询会创建一个包含原始密钥字节的名为 CustomerRawKeys 的客户 ID 表和一个名为 CustomerIds 的唯一 ID 表。查询会为每个 customer_id 创建一个新的 'AEAD_AES_GCM_256' 密钥集;然后使用与该 customer_id 相对应的 raw_key_bytes 值向每个密钥集添加新密钥。输出是一个表,表中的每一行包含一个 customer_id 和一个 BYTES 形式的密钥集(包含使用 KEYS.ADD_KEY_FROM_RAW_BYTES 添加的原始密钥)。

WITH CustomerRawKeys AS (
  SELECT 1 AS customer_id, b'0123456789012345' AS raw_key_bytes UNION ALL
  SELECT 2, b'9876543210543210' UNION ALL
  SELECT 3, b'0123012301230123'
), CustomerIds AS (
  SELECT 1 AS customer_id UNION ALL
  SELECT 2 UNION ALL
  SELECT 3
)
SELECT
  ci.customer_id,
  KEYS.ADD_KEY_FROM_RAW_BYTES(
    KEYS.NEW_KEYSET('AEAD_AES_GCM_256'),
    'AES_CBC_PKCS',
    (SELECT raw_key_bytes FROM CustomerRawKeys AS crk
     WHERE crk.customer_id = ci.customer_id)
  ) AS keyset
FROM CustomerIds AS ci;

每个输出密钥集包含两项:使用 KEYS.NEW_KEYSET('AEAD_AES_GCM_256') 创建的主要加密密钥和使用 KEYS.ADD_KEY_FROM_RAW_BYTES 添加的原始密钥。如果输出中的密钥集与 AEAD.ENCRYPT 结合使用,则 BigQuery 会使用 KEYS.NEW_KEYSET('AEAD_AES_GCM_256') 创建的主要加密密钥来加密输入明文。如果密钥集与 AEAD.DECRYPT_STRINGAEAD.DECRYPT_BYTES 结合使用,且任一密钥成功解密密文,则 BigQuery 会返回产生的明文。

AEAD.DECRYPT_BYTES

AEAD.DECRYPT_BYTES(keyset, ciphertext, additional_data)

说明

使用 keyset 中的匹配密钥来解密 ciphertext 并使用 additional_data 验证数据的完整性。如果解密或验证失败,则返回错误。

keyset 是其中一个 KEYS 函数返回的序列化 BYTES 值。keyset 必须包含用于加密 ciphertext 的密钥,该密钥必须处于 'ENABLED' 状态,否则函数会返回错误。AEAD.DECRYPT_BYTES 通过查找密钥 ID 与 ciphertext 中加密的密钥相匹配的密钥,来识别 keyset 中的匹配密钥。

ciphertextBYTES 值,它是调用 AEAD.ENCRYPT 的结果,其中输入 plaintext 的类型为 BYTES

additional_dataSTRINGBYTES 值,可确保所加密数据的真实性和完整性。此函数将任何 STRING 值转换为 BYTES。此变量必须与提供给 AEAD.ENCRYPT 用于加密 ciphertextadditional_data 相同(忽略其类型),否则函数会返回错误。

返回数据类型

BYTES

示例

此示例会创建唯一 ID 的表,其中包含相关明文值和密钥集。然后,它使用这些密钥集将明文值加密为 BYTES 并将其存储在新表中。最后,它使用 AEAD.DECRYPT_BYTES 解密已加密的值,并将其显示为明文。

以下语句创建了表 CustomerKeysets,其中包含唯一 ID 列、AEAD_AES_GCM_256 密钥集列和最喜欢的动物列。

CREATE TABLE aead.CustomerKeysets AS
SELECT
  1 AS customer_id,
  KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset,
  'jaguar' AS favorite_animal
UNION ALL
SELECT
  2 AS customer_id,
  KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset,
  'zebra' AS favorite_animal
UNION ALL
SELECT
  3 AS customer_id,
  KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset,
  'nautilus' AS favorite_animal;

以下语句创建了表 EncryptedCustomerData,其中包含唯一 ID 列和密文列。该语句使用 CustomerKeysets 中与每个唯一 ID 相对应的密钥集值来加密明文 favorite_animal

CREATE TABLE aead.EncryptedCustomerData AS
SELECT
  customer_id,
  AEAD.ENCRYPT(keyset, favorite_animal, CAST(customer_id AS STRING))
   AS encrypted_animal
FROM
  aead.CustomerKeysets AS ck;

以下查询使用 CustomerKeysets 表中的密钥集来解密 EncryptedCustomerData 表中的数据。

SELECT
  ecd.customer_id,
  AEAD.DECRYPT_STRING(
    (SELECT ck.keyset
     FROM aead.CustomerKeysets AS ck
     WHERE ecd.customer_id = ck.customer_id),
    ecd.encrypted_animal,
    CAST(ecd.customer_id AS STRING)
  ) AS favorite_animal
FROM aead.EncryptedCustomerData AS ecd;

AEAD.DECRYPT_STRING

AEAD.DECRYPT_STRING(keyset, ciphertext, additional_data)

说明

AEAD.DECRYPT_BYTES 类似,但 ciphertextAEAD.ENCRYPTBYTES 输出,其中 AEAD.ENCRYPTplaintext 输入的类型为 STRING,而不是 BYTES

返回数据类型

STRING

AEAD.ENCRYPT

AEAD.ENCRYPT(keyset, plaintext, additional_data)

说明

使用 keyset 中的算法和主要加密密钥来加密明文。将 additional_data 合并到返回的密文中。如果任何输入是 NULL,则返回 NULL

keyset 是其中一个 KEYS 函数返回的序列化 BYTES 值。

plaintext 是要加密的 STRINGBYTES 值。

additional_data 是要合并到返回的密文中的 STRINGBYTES 值。plaintextadditional_data 的类型必须相同。 AEAD.ENCRYPT(keyset, string1, string2) 等同于 AEAD.ENCRYPT(keyset, CAST(string1 AS BYTES), CAST(string2 AS BYTES))

输出是密文 BYTES。密文将包含特定于 Tink 的前缀,该前缀指示执行加密所用的密钥(该密钥是 'AES_GCM' 密钥时除外)。

返回数据类型

BYTES

示例

以下查询使用 CustomerKeysets 表中每个 customer_id 的密钥集来加密 PlaintextCustomerData 表中与该 customer_id 相对应的明文 favorite_animal 的值。输出包含 customer_id 值的列和 BYTES 形式的相应密文输出的列。

WITH CustomerKeysets AS (
  SELECT 1 AS customer_id, KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset UNION ALL
  SELECT 2, KEYS.NEW_KEYSET('AEAD_AES_GCM_256') UNION ALL
  SELECT 3, KEYS.NEW_KEYSET('AEAD_AES_GCM_256')
), PlaintextCustomerData AS (
  SELECT 1 AS customer_id, 'elephant' AS favorite_animal UNION ALL
  SELECT 2, 'walrus' UNION ALL
  SELECT 3, 'leopard'
)
SELECT
  pcd.customer_id,
  AEAD.ENCRYPT(
    (SELECT keyset
     FROM CustomerKeysets AS ck
     WHERE ck.customer_id = pcd.customer_id),
    pcd.favorite_animal,
    CAST(pcd.customer_id AS STRING)
  ) AS encrypted_animal
FROM PlaintextCustomerData AS pcd;

KEYS.KEYSET_FROM_JSON

KEYS.KEYSET_FROM_JSON(json_keyset)

说明

返回序列化 BYTES 形式的输入 json_keyset STRING,这是其他 KEYSAEAD 函数的有效输入。JSON STRING 必须与 google.crypto.tink.Keyset 协议缓冲区消息的定义兼容:JSON 密钥集应为 JSON 对象,包含与 google.crypto.tink.Keyset 定义中的“keyset”消息中的内容相对应的对象和名称-值对。您可以使用 KEYS.KEYSET_TO_JSON 将序列化 BYTES 形式的输出转换回 JSON STRING

返回数据类型

BYTES

示例

KEYS.KEYSET_FROM_JSON 接受 JSON 格式的 STRING 值,如下所示:

{
  "key":[
      {
        "keyData":{
          "keyMaterialType":"SYMMETRIC",
          "typeUrl":"type.googleapis.com/google.crypto.tink.AesGcmKey",
          "value":"GiD80Z8kL6AP3iSNHhqseZGAIvq7TVQzClT7FQy8YwK3OQ=="
        },
        "keyId":3101427138,
        "outputPrefixType":"TINK",
        "status":"ENABLED"
      }
    ],
  "primaryKeyId":3101427138
}

以下查询根据 JSON 格式的 STRING json_keyset 创建一个新密钥集:

SELECT KEYS.KEYSET_FROM_JSON(json_keyset);

将返回序列化为 BYTESjson_keyset,如下所示:

\x08\x9d\x8e\x85\x82\x09\x12d\x0aX\x0a0
type.googleapis.com/google.crypto.tink.AesGcmKey\x12\"\x1a qX\xe4IG\x87\x1f\xde
\xe3)+e\x98\x0a\x1c}\xfe\x88<\x12\xeb\xc1t\xb8\x83\x1a\xcd\xa8\x97\x84g\x18\x01
\x10\x01\x18\x9d\x8e\x85\x82\x09 \x01

KEYS.KEYSET_TO_JSON

KEYS.KEYSET_TO_JSON(keyset)

说明

返回 JSON STRING 形式的输入 keyset。返回的 JSON STRINGgoogle.crypto.tink.Keyset 协议缓冲区消息的定义兼容。您可以使用 KEYS.KEYSET_FROM_JSON 将 JSON STRING 形式转换回 BYTES

返回数据类型

STRING

示例

以下查询会以 JSON 格式的 STRING 返回新的 'AEAD_AES_GCM_256' 密钥集。

SELECT KEYS.KEYSET_TO_JSON(KEYS.NEW_KEYSET('AEAD_AES_GCM_256'));

结果是 STRING,如下所示。

{
  "key":[
      {
        "keyData":{
          "keyMaterialType":"SYMMETRIC",
          "typeUrl":"type.googleapis.com/google.crypto.tink.AesGcmKey",
          "value":"GiD80Z8kL6AP3iSNHhqseZGAIvq7TVQzClT7FQy8YwK3OQ=="
        },
        "keyId":3101427138,
        "outputPrefixType":"TINK",
        "status":"ENABLED"
      }
    ],
  "primaryKeyId":3101427138
}

KEYS.ROTATE_KEYSET

KEYS.ROTATE_KEYSET(keyset, key_type)

说明

根据 key_typekeyset 添加新密钥。该新密钥将成为新密钥集的主要加密密钥。返回序列化为 BYTES 的新密钥集。

输入 keyset 中的旧主要加密密钥仍是返回的密钥集中的额外密钥。

返回数据类型

BYTES

示例

以下语句会创建一个表,其中包含唯一 customer_id 值的列和 'AEAD_AES_GCM_256' 密钥集。然后,它使用 KEYS.ROTATE_KEYSET 在源表中的每个密钥集中创建一个新的主要加密密钥。输出中的每行包含一个 customer_id 和一个 BYTES 形式的 'AEAD_AES_GCM_256' 密钥集。

WITH ExistingKeysets AS (
SELECT 1 AS customer_id, KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset
    UNION ALL
  SELECT 2, KEYS.NEW_KEYSET('AEAD_AES_GCM_256') UNION ALL
  SELECT 3, KEYS.NEW_KEYSET('AEAD_AES_GCM_256')
)
SELECT customer_id, KEYS.ROTATE_KEYSET(keyset, 'AEAD_AES_GCM_256') AS keyset
FROM ExistingKeysets;
此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

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