Funciones de encriptación AEAD

En las siguientes secciones, se describen las funciones de encriptación AEAD que se admiten en BigQuery. Para obtener una descripción de cómo se usan las funciones de encriptación AEAD, consulta Conceptos de encriptación AEAD.

KEYS.NEW_KEYSET

KEYS.NEW_KEYSET(key_type)

Descripción

Muestra un conjunto de claves serializado que contiene una clave nueva basada en key_type. El conjunto de claves que se muestra es una representación serializada en BYTES de google.crypto.tink.Keyset que contiene una clave criptográfica principal, sin claves adicionales. Puedes usar el conjunto de claves con las funciones AEAD.ENCRYPT, AEAD.DECRYPT_BYTES y AEAD.DECRYPT_STRING para la encriptación y desencriptación, así como con el grupo KEYS de funciones relacionadas con las claves y el conjunto de claves.

key_type es una representación literal en STRING del tipo de clave que se creará. key_type no puede ser NULL. key_type puede ser alguno de los siguientes:

  • AEAD_AES_GCM_256: Crea una clave de 256 bits con el generador de números seudoaleatorio proporcionado por boringSSL. La clave usa AES-GCM para las operaciones de encriptación y desencriptación.

Tipo de datos mostrados

BYTES

Ejemplo

En la siguiente consulta, se crea un conjunto de claves para cada fila en CustomerIds, que puede usarse después a fin de encriptar los datos. Cada conjunto de claves contiene una sola clave de encriptación con datos de claves generados de forma aleatoria. Cada fila del resultado contiene un customer_id y una clave 'AEAD_AES_GCM_256' en BYTES.

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)

Descripción

Muestra un conjunto de claves serializado como BYTES con la adición de una clave a keyset basada en key_type y raw_key_bytes.

La clave criptográfica principal sigue siendo la misma que en keyset. La longitud esperada de raw_key_bytes depende del valor de key_type. Los siguientes son key_types compatibles:

  • 'AES_CBC_PKCS': crea una clave para la desencriptación AES mediante el encadenamiento de bloques de cifrado y el relleno de PKCS. Se espera que raw_key_bytes sea un valor en BYTES de clave sin procesar de  16, 24 o 32 de longitud; estas longitudes tienen tamaños de 128, 192 y 256 bits, respectivamente. Las funciones AEAD de BigQuery no admiten claves de estos tipos para la encriptación; en su lugar, se prefieren las teclas 'AEAD_AES_GCM_256' o 'AES_GCM'.
  • 'AES_GCM': crea una clave para la encriptación o desencriptación de AES con Galois/Counter Mode. raw_key_bytes debe ser un valor BYTES de clave sin procesar de 16 o 32 longitud; estas longitudes tienen tamaños de 128 y 256 bits, respectivamente. Cuando se usan claves de este tipo como entrada para AEAD.ENCRYPT, el cifrado resultante no tiene un prefijo específico de Tink que indique cuál fue la clave usada.

Tipo de datos mostrados

BYTES

Ejemplo

La siguiente consulta crea una tabla de ID de cliente junto con bytes de clave sin procesar, denominada CustomerRawKeys, y una tabla de ID únicos, llamada CustomerIds. Crea un conjunto de claves 'AEAD_AES_GCM_256' nuevo para cada customer_id; luego agrega una clave nueva a cada conjunto de claves, mediante el uso del valor raw_key_bytes correspondiente a ese customer_id. El resultado es una tabla en la que cada fila contiene un customer_id y un conjunto de claves en BYTES, que contiene la clave sin procesar que se agregó mediante 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;

Los conjuntos de claves de salida contienen dos elementos cada uno: la clave criptográfica principal creada con KEYS.NEW_KEYSET('AEAD_AES_GCM_256') y la clave sin procesar que se agregó mediante KEYS.ADD_KEY_FROM_RAW_BYTES. Si se usa un conjunto de claves resultantes con AEAD.ENCRYPT, BigQuery usa la clave criptográfica principal creada con KEYS.NEW_KEYSET('AEAD_AES_GCM_256') para encriptar el texto sin formato de entrada. Si el conjunto de claves se usa con AEAD.DECRYPT_STRING o AEAD.DECRYPT_BYTES, BigQuery muestra el texto sin formato resultante si alguna de las dos claves tiene éxito al desencriptar el texto cifrado.

AEAD.DECRYPT_BYTES

AEAD.DECRYPT_BYTES(keyset, ciphertext, additional_data)

Descripción

Usa la clave de coincidencia de keyset para desencriptar ciphertext y verifica la integridad de los datos mediante additional_data. Muestra un error si la desencriptación o la verificación fallan.

keyset es un valor en BYTES serializado mostrado por una de las funciones KEYS o una STRUCT que muestra KEYS.KEYSET_CHAIN. keyset debe contener la clave que se usó para encriptar el ciphertext, y la clave debe estar en un estado 'ENABLED', de lo contrario, la función mostrará un error AEAD.DECRYPT_BYTES identifica la clave que coincide en el keyset. Para ello, busca la clave con el ID de clave correspondiente al que está encriptado en el ciphertext.

ciphertext es un valor en BYTES que es el resultado de una llamada a AEAD.ENCRYPT donde la entrada plaintext era del tipo BYTES.

Si ciphertext incluye un vector de inicialización (IV), debe ser los primeros bytes de ciphertext. Si ciphertext incluye una etiqueta de autenticación, deben ser los últimos bytes de ciphertext. Si la etiqueta IV y la autenticidad son una (SIV), deben ser los primeros bytes de ciphertext. Por lo general, la etiqueta IV y la etiqueta de autenticación requieren 16 bytes, pero su tamaño puede variar.

additional_data es un valor STRING o BYTES que garantiza la autenticidad y la integridad de los datos encriptados. Esta función arroja cualquier valor STRING a BYTES. Debe ser el mismo que el additional_data proporcionado a AEAD.ENCRYPT para encriptar ciphertext, sin importar su tipo, de lo contrario, la función mostrará un error.

Tipo de datos mostrados

BYTES

Ejemplo

En este ejemplo, se crea una tabla de ID únicos con valores de texto sin formato y conjuntos de claves asociados. Luego, usa estos conjuntos de claves para encriptar los valores de texto sin formato como BYTES y almacenarlos en una tabla nueva. Por último, usa AEAD.DECRYPT_BYTES para desencriptar los valores encriptados y mostrarlos como texto sin formato.

La siguiente declaración crea una tabla CustomerKeysets que contiene una columna de ID únicos, una columna de conjuntos de claves AEAD_AES_GCM_256 y una columna de animales favoritos.

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

La siguiente instrucción crea una tabla EncryptedCustomerData que contiene una columna de ID únicos y una columna de cifrado. La instrucción encripta el texto sin formato favorite_animal con el valor del conjunto de claves de CustomerKeysets correspondiente a cada ID único.

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

La siguiente consulta usa los conjuntos de claves en la tabla CustomerKeysets para desencriptar datos en la tabla EncryptedCustomerData.

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

AEAD.DECRYPT_STRING

AEAD.DECRYPT_STRING(keyset, ciphertext, additional_data)

Descripción

Es similar a AEAD.DECRYPT_BYTES, pero en este, plaintext es de tipo STRING.

Tipo de datos mostrados

STRING

AEAD.ENCRYPT

AEAD.ENCRYPT(keyset, plaintext, additional_data)

Descripción

Encripta plaintext mediante la clave criptográfica principal de keyset. El algoritmo de la clave primaria debe ser AEAD_AES_GCM_256. Incorpora additional_data en el texto cifrado que se muestra. Muestra NULL si alguna entrada es NULL.

keyset es un valor en BYTES serializado mostrado por una de las funciones KEYS o una STRUCT que muestra KEYS.KEYSET_CHAIN.

plaintext es el valor de STRING o en BYTES que se encriptará.

additional_data es un valor STRING o BYTES para incorporar en el texto cifrado que se muestra. plaintext y additional_data deben ser del mismo tipo. AEAD.ENCRYPT(keyset, string1, string2) es equivalente a AEAD.ENCRYPT(keyset, CAST(string1 AS BYTES), CAST(string2 AS BYTES)).

El resultado es el texto cifrado BYTES. El texto cifrado contiene un prefijo específico de Tink que indica la clave usada para realizar la encriptación.

Tipo de datos mostrados

BYTES

Ejemplo

En la siguiente consulta, se usan los conjuntos de claves de cada customer_id en la tabla CustomerKeysets para encriptar el valor del texto sin formato favorite_animal en la tabla PlaintextCustomerData correspondiente a ese customer_id. El resultado contiene una columna de valores customer_id y una columna del resultado de texto cifrado correspondiente en 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_CHAIN

KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset)

Descripción

Se puede usar en lugar del argumento keyset para AEAD.

funciones para pasar un conjunto de claves encriptado con una clave de Cloud KMS. Esto te permite usar funciones de AEAD sin incluir claves de texto simple en una consulta.

kms_resource_name es un valor STRING que contiene la ruta de acceso al recurso a la clave de Cloud KMS que se usa para desencriptar first_level_keyset. La string completa debe comenzar con gcp-kms:// y tener el siguiente formato: gcp-kms://projects/{id}/locations/{location}/keyRings/{id}/cryptoKeys/{id}. La clave de Cloud KMS debe residir en la misma región de Cloud que la consulta.

first_level_keyset es un valor BYTES que contiene el texto cifrado que se generó mediante la encriptación de un conjunto de claves Tink serializado con la clave de KMS especificada.

kms_resource_name y first_level_keyset deben ser valores constantes.

Tipo de datos mostrados

STRUCT

Ejemplo

En este ejemplo, se crea una tabla de datos de ejemplo y, luego, se muestra cómo encriptar esos datos mediante un conjunto de claves unidas (encriptadas). Por último, se muestra cómo consultar la versión encriptada de los datos.

La siguiente instrucción crea una tabla RawCustomerData que contiene una columna de ID de cliente y una columna de animales favoritos.

CREATE TABLE aead.RawCustomerData AS
SELECT
  1 AS customer_id,
  b'jaguar' AS favorite_animal
UNION ALL
SELECT
  2 AS customer_id,
  b'zebra' AS favorite_animal
UNION ALL
SELECT
  3 AS customer_id,
  b'zebra' AS favorite_animal;

La siguiente instrucción crea una tabla EncryptedCustomerData que contiene una columna de ID únicos y una columna de cifrado. La instrucción encripta el texto simple favorite_animal con el primer valor_levelset proporcionado.

SET kms_resource_name = 'gcp-kms://projects/my-project/locations/us/keyRings/my-key-ring/cryptoKeys/my-crypto-key';
SET first_level_keyset = b'\012\044\000\107\275\360\176\264\206\332\235\215\304...';

CREATE TABLE aead.EncryptedCustomerData AS
SELECT
  customer_id,
  AEAD.ENCRYPT(
    KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset),
    favorite_animal,
    CAST(CAST(customer_id AS STRING) AS BYTES)
  ) AS encrypted_animal
FROM
  aead.RawCustomerData;

La siguiente consulta usa el primer_level_keyset para desencriptar los datos en la tabla EncryptedCustomerData.

SET kms_resource_name = 'gcp-kms://projects/my-project/locations/us/keyRings/my-key-ring/cryptoKeys/my-crypto-key';
SET first_level_keyset = b'\012\044\000\107\275\360\176\264\206\332\235\215\304...';

SELECT
  customer_id,
  AEAD.DECRYPT_BYTES(
    KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset)
    encrypted_animal,
    CAST(CAST(customer_id AS STRING) AS BYTES)
  ) AS favorite_animal
FROM aead.EncryptedCustomerData;

KEYS.KEYSET_FROM_JSON

KEYS.KEYSET_FROM_JSON(json_keyset)

Descripción

Muestra la entrada json_keyset STRING en forma de BYTES serializados, que es una entrada válida para otras funciones KEYS y AEAD. El STRING JSON debe ser compatible con la definición del mensaje de búfer de protocolo google.crypto.tink.Keyset: el conjunto de claves JSON debe ser un objeto JSON que contenga objetos y pares de nombre-valor correspondientes a esos en el mensaje “conjunto de claves” en la definición en google.crypto.tink.Keyset. La representación resultante en BYTES serializados puede volver a convertirse en una STRING JSON mediante KEYS.KEYSET_TO_JSON.

Tipo de datos mostrados

BYTES

Ejemplo

KEYS.KEYSET_FROM_JSON toma valores de STRING con formato JSON como los siguientes:

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

La siguiente consulta crea un nuevo conjunto de claves a partir de un STRING json_keyset con formato JSON:

SELECT KEYS.KEYSET_FROM_JSON(json_keyset);

Esto muestra el json_keyset serializado en BYTES, como el siguiente:

\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)

Descripción

Muestra una representación de STRING de JSON del keyset de entrada. La STRING de JSON que se muestra es compatible con la definición del mensaje de búfer de protocolo google.crypto.tink.Keyset Puedes convertir la representación de JSON STRING de nuevo en BYTES con KEYS.KEYSET_FROM_JSON.

Tipo de datos mostrados

STRING

Ejemplo

La siguiente consulta muestra un nuevo conjunto de claves 'AEAD_AES_GCM_256' como una STRING con formato JSON.

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

El resultado es una STRING como la siguiente.

{
  "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)

Descripción

Agrega una nueva clave a keyset en función de key_type. Esta clave nueva se convierte en la clave criptográfica principal del nuevo conjunto de claves. Muestra el nuevo conjunto de claves serializado en BYTES.

La antigua clave criptográfica primaria del keyset de entrada sigue siendo una clave adicional en el conjunto de claves mostrado.

El key_type nuevo debe coincidir con el tipo de clave existente en keyset.

Tipo de datos mostrados

BYTES

Ejemplo

La siguiente instrucción crea una tabla que contiene una columna de valores únicos customer_id y conjuntos de teclas 'AEAD_AES_GCM_256'. Luego, crea una nueva clave criptográfica primaria dentro de cada conjunto de claves en la tabla fuente con KEYS.ROTATE_KEYSET. Cada fila del resultado contiene un customer_id y un conjunto de claves 'AEAD_AES_GCM_256' en BYTES.

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;

KEYS.KEYSET_LENGTH

KEYS.KEYSET_LENGTH(keyset)

Descripción

Muestra la cantidad de claves en el conjunto de claves proporcionado.

Tipo de datos mostrados

INT64

Ejemplo

En este ejemplo se hace referencia a una STRING con formato JSON llamada json_keyset que contiene dos claves:

{
   "primaryKeyId":1354994251,
   "key":[
      {
         "keyData":{
            "keyMaterialType":"SYMMETRIC",
            "typeUrl":"type.googleapis.com/google.crypto.tink.AesGcmKey",
            "value":"GiD9sxQRgFj4aYN78vaIlxInjZkG/uvyWSY9a8GN+ELV2Q=="
         },
         "keyId":1354994251,
         "outputPrefixType":"TINK",
         "status":"ENABLED"
      }
   ],
   "key":[
      {
         "keyData":{
            "keyMaterialType":"SYMMETRIC",
            "typeUrl":"type.googleapis.com/google.crypto.tink.AesGcmKey",
            "value":"PRn76sxQRgFj4aYN00vaIlxInjZkG/uvyWSY9a2bLRm"
         },
         "keyId":852264701,
         "outputPrefixType":"TINK",
         "status":"DISABLED"
      }
   ]
}

La siguiente consulta convierte json_keyset en un conjunto de claves y, luego, muestra la cantidad de claves en el conjunto:

SELECT KEYS.KEYSET_LENGTH(KEYS.KEYSET_FROM_JSON(json_keyset)) as key_count;

+-----------+
| key_count |
+-----------+
| 2         |
+-----------+