GoogleSQL para BigQuery admite el cifrado AEAD (Authenticated Encryption with Associated Data).
En este tema se explican los conceptos de cifrado AEAD en GoogleSQL. Para obtener una descripción de las diferentes funciones de encriptado AEAD que admite GoogleSQL, consulte Funciones de encriptado AEAD.
Finalidad del cifrado AEAD
BigQuery protege tus datos mediante el cifrado en reposo. BigQuery también admite claves de cifrado gestionadas por el cliente (CMEKs), que te permiten cifrar tablas con claves de cifrado específicas. Sin embargo, en algunos casos, puede que quieras cifrar valores concretos de una tabla.
Por ejemplo, supongamos que quieres conservar los datos de todos tus clientes en una tabla común y cifrar los datos de cada cliente con una clave diferente. Tienes datos repartidos en varias tablas que quieres poder "eliminar con cifrado". La eliminación criptográfica es el proceso de eliminar una clave de cifrado para que los datos cifrados con esa clave sean ilegibles.
Las funciones de encriptado AEAD te permiten crear conjuntos de claves que contienen claves para encriptar y descifrar, usar estas claves para encriptar y descifrar valores individuales de una tabla, y rotar claves dentro de un conjunto de claves.
Conjuntos de claves
Un conjunto de claves es una colección de claves criptográficas, una de las cuales es la clave criptográfica principal y el resto, si las hay, son claves criptográficas secundarias. Cada clave codifica un algoritmo de cifrado o descifrado, si la clave está habilitada, inhabilitada o destruida y, en el caso de las claves no destruidas, los bytes de la clave. La clave criptográfica principal determina cómo cifrar el texto sin formato de entrada. La clave criptográfica principal nunca puede estar inhabilitada. Las claves criptográficas secundarias solo se usan para descifrar y pueden estar habilitadas o inhabilitadas. Un conjunto de claves se puede usar para descifrar cualquier dato que se haya cifrado con él.
En GoogleSQL, un conjunto de claves se representa como un búfer de protocolo google.crypto.tink.Keyset serializado en BYTES
.
Ejemplo
A continuación se muestra un ejemplo de un conjunto de claves AEAD, representado como una cadena JSON, con tres claves.
{
"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"
}
]
}
En el ejemplo anterior, la clave criptográfica principal tiene el ID 569259624
y es la primera clave que aparece en la cadena JSON. Hay dos claves criptográficas secundarias: una con el ID 852264701
en estado inhabilitado y otra con el ID 237910588
en estado eliminado. Cuando una función de cifrado AEAD usa este conjunto de claves para cifrar, el texto cifrado resultante codifica el ID de la clave criptográfica principal de 569259624
.
Cuando una función AEAD usa este conjunto de claves para el descifrado, la función elige la clave adecuada para el descifrado en función del ID de clave codificado en el texto cifrado. En el ejemplo anterior, si se intenta descifrar con los IDs de clave 852264701
o 237910588
, se producirá un error, ya que el ID de clave 852264701
está inhabilitado y el ID 237910588
se ha destruido. Si se restaura el ID de clave 852264701
a un estado habilitado, se podrá usar para descifrar.
El tipo de clave determina el modo de cifrado que se va a usar con esa clave.
Si se cifra texto sin formato más de una vez con el mismo conjunto de claves, generalmente se devuelven valores de texto cifrado diferentes debido a los diferentes vectores de inicialización (IVs), que se eligen mediante el generador de números pseudoaleatorios proporcionado por OpenSSL.
Conjuntos de claves encapsulados
Si necesitas gestionar un conjunto de claves de forma segura o transmitirlo a través de un canal no fiable, puedes usar un conjunto de claves envuelto. Cuando encapsulas un conjunto de claves sin formato, este proceso encripta el conjunto de claves sin formato mediante una clave de Cloud KMS.
Los conjuntos de claves envueltos pueden cifrar y descifrar datos sin exponer los datos del conjunto de claves. Aunque puede haber otras formas de restringir el acceso a los datos a nivel de campo, los conjuntos de claves envueltos proporcionan un mecanismo más seguro para gestionar los conjuntos de claves que los conjuntos de claves sin envolver.
Al igual que los conjuntos de claves, los conjuntos de claves encapsulados se pueden y se deben rotar periódicamente. Los conjuntos de claves encapsuladas se usan en las funciones de encriptado de envolvente AEAD.
Aquí tienes algunas funciones con ejemplos de conjuntos de claves envueltos:
KEYS.NEW_WRAPPED_KEYSET
: crea un nuevo conjunto de claves envuelto.KEYS.ROTATE_WRAPPED_KEYSET
: rota un conjunto de claves encapsuladas.KEYS.REWRAP_KEYSET
: vuelve a envolver un conjunto de claves envuelto con datos nuevos.KEYS.KEYSET_CHAIN
: obtiene un conjunto de claves de Tink cifrado con una clave de Cloud KMS.
Estándar de cifrado avanzado (AES)
Las funciones de encriptado AEAD usan el estándar de encriptado avanzado (AES). El cifrado AES toma texto sin formato como entrada, junto con una clave criptográfica, y devuelve una secuencia de bytes cifrada como salida. Esta secuencia de bytes se puede descifrar más adelante con la misma clave que se usó para cifrarla. AES usa un tamaño de bloque de 16 bytes, lo que significa que el texto sin formato se trata como una secuencia de bloques de 16 bytes. El texto cifrado contendrá un prefijo específico de Tink que indica la clave utilizada para realizar el cifrado. El cifrado AES admite varios modos de cifrado por bloques.
Modos de cifrado por bloques
Los dos modos de cifrado por bloques admitidos por las funciones de cifrado AEAD son GCM y CBC.
GCM
Modo Galois/Counter (GCM) es un modo de cifrado AES. La función numera los bloques de forma secuencial y, a continuación, combina este número de bloque con un vector de inicialización (IV). Un vector de inicialización es un valor aleatorio o pseudoaleatorio que constituye la base de la aleatorización de los datos de texto sin formato. A continuación, la función cifra el número de bloque y el IV combinados mediante AES. A continuación, la función realiza una operación lógica de OR exclusivo (XOR) a nivel de bits en el resultado del cifrado y el texto sin cifrar para generar el texto cifrado. El modo GCM usa una clave criptográfica de 128 o 256 bits.
Modo CBC
CBC "encadena" bloques aplicando XOR a cada bloque de texto sin cifrar con el bloque de texto cifrado anterior antes de cifrarlo. El modo CBC usa una clave criptográfica de 128, 192 o 256 bits. CBC usa un vector de inicialización de 16 bytes como bloque inicial y aplica XOR a este bloque con el primer bloque de texto sin formato.
El modo CBC no es un esquema AEAD en el sentido criptográfico, ya que no proporciona integridad de los datos. Es decir, no se detectarán las modificaciones maliciosas de los datos cifrados, lo que también pone en peligro la confidencialidad de los datos. Por lo tanto, no se recomienda usar CBC a menos que sea necesario por motivos de compatibilidad con versiones anteriores.
Datos adicionales
Las funciones de cifrado AEAD admiten el uso de un argumento additional_data
, también conocido como datos asociados (AD) o datos autenticados adicionales.
Un texto cifrado solo se puede descifrar si se proporciona la misma información adicional que se usó para cifrarlo. Por lo tanto, los datos adicionales se pueden usar para vincular el texto cifrado a un contexto.
Por ejemplo, additional_data
podría ser el resultado de
CAST(customer_id AS STRING)
al cifrar datos de un cliente concreto.
De esta forma, nos aseguramos de que, cuando se descifren los datos, se hayan cifrado previamente con el customer_id
esperado. Se necesita el mismo valor de additional_data
para descifrar. Para obtener más información, consulta RFC 5116.
Desencriptado
El resultado de AEAD.ENCRYPT
es
texto cifrado BYTES
. Las funciones AEAD.DECRYPT_STRING
o AEAD.DECRYPT_BYTES
pueden descifrar este texto cifrado. Estas funciones deben usar un conjunto de claves que contenga la clave que se usó para el cifrado. Esa clave debe estar en estado 'ENABLED'
. También deben usar el mismo additional_data
que se usó en el cifrado.
Cuando se usa el conjunto de claves para el descifrado, se elige la clave adecuada para el descifrado en función del ID de clave codificado en el texto cifrado.
El resultado de AEAD.DECRYPT_STRING
es una CADENA de texto sin formato, mientras que el resultado de AEAD.DECRYPT_BYTES
es texto sin formato BYTES
. AEAD.DECRYPT_STRING
puede descifrar texto cifrado que codifica un valor STRING.
AEAD.DECRYPT_BYTES
puede descifrar texto cifrado que codifica un valor BYTES
. Si se usa una de estas funciones para descifrar un texto cifrado que codifica el tipo de datos incorrecto (por ejemplo, si se usa AEAD.DECRYPT_STRING
para descifrar un texto cifrado que codifica un valor BYTES
), se producirá un comportamiento indefinido y puede que se genere un error.
Rotación de claves
El objetivo principal de rotar las claves de cifrado es reducir la cantidad de datos cifrados con una clave concreta, de modo que, si se vulnera una clave, un atacante pueda acceder a menos datos.
La rotación de conjuntos de claves implica lo siguiente:
- Crear una clave criptográfica principal en cada conjunto de claves.
- Descifrar y volver a cifrar todos los datos cifrados.
La función KEYS.ROTATE_KEYSET
o KEYS.ROTATE_WRAPPED_KEYSET
realiza el primer paso, que consiste en añadir una nueva clave criptográfica principal a un conjunto de claves y cambiar la clave criptográfica principal antigua a una clave criptográfica secundaria.
Claves de Cloud KMS
GoogleSQL admite funciones de cifrado AEAD con claves de Cloud KMS para proteger aún más tus datos. Esta capa de protección adicional cifra tu clave de cifrado de datos (DEK) con una clave de cifrado de claves (KEK). La KEK es un conjunto de claves de encriptado simétricas que se almacena de forma segura en Cloud Key Management Service y se gestiona mediante permisos y roles de Cloud KMS.
En el momento de la ejecución de la consulta, usa la función KEYS.KEYSET_CHAIN
para proporcionar la ruta de recurso de KMS de la KEK y el texto cifrado de la DEK encapsulada. BigQuery llama a Cloud KMS para desencapsular la DEK y, a continuación, usa esa clave para descifrar los datos de tu consulta. La versión desencapsulada de la DEK solo se almacena en la memoria durante la consulta y, después, se destruye.
Para obtener más información, consulta el artículo sobre el encriptado a nivel de columna de SQL con claves de Cloud KMS.