Encriptación a nivel de columnas con Cloud KMS
Puedes usar Cloud Key Management Service (Cloud KMS) para encriptar las claves que, a su vez, encriptan los valores dentro de las tablas de BigQuery. Puedes usar las funciones de encriptación AEAD con conjuntos de claves o conjuntos de claves unidos de Cloud KMS para proporcionar una segunda capa de protección a nivel de la columna.
Introducción
Para proporcionar una capa adicional de protección, Cloud KMS encripta tu clave de encriptación de datos (DEK) con una segunda clave de encriptación de claves (KEK). En BigQuery, hacer referencia a un conjunto de claves encriptado en lugar de a un texto sin formato ayuda a reducir el riesgo de exposición de claves. La KEK es un conjunto de claves de encriptación simétrica que se almacena de forma segura en Cloud KMS y se administra mediante funciones y permisos de Identity and Access Management (IAM).
BigQuery admite funciones de encriptación deterministas y no deterministas. Con la encriptación determinista, si los datos almacenados y los datos autenticados adicionales (opcionales) son idénticos, el texto cifrado es idéntico. Esto permite la agregación y las uniones en función de la columna encriptada. Con la encriptación no determinista, el texto cifrado almacenado es único sin importar los datos encriptados, lo que evita el agrupamiento en clústeres, la agregación y las uniones.
En el momento de la ejecución de la consulta, debes proporcionar la ruta de acceso de recursos de Cloud KMS de la KEK y el texto cifrado de la DEK unida. BigQuery llama a Cloud KMS para separar la DEK y, luego, usa esa clave a fin de desencriptar los datos en tu consulta. La versión separada de la DEK solo se almacena en la memoria durante la consulta y, luego, se destruye.
Si usas Cloud KMS en una región en la que es compatible Cloud External Key Manager, puedes usar claves basadas en Cloud EKM en Cloud KMS.
Casos de uso
A continuación, se presentan los casos de uso de encriptación con claves de Cloud KMS:
- Datos encriptados de forma externa que deben almacenarse en BigQuery sin almacenar el conjunto de claves en texto simple. Luego, tus datos se pueden exportar desde la tabla BQ o desencriptar con una consulta de SQL.
- “Control de acceso doble” en datos encriptados en BigQuery. Un usuario debe tener permiso tanto para la tabla como para la clave de encriptación para leer datos en el texto simple.
Matriz de permisos del usuario | ||
---|---|---|
Permiso en la tabla | Sin permiso en la tabla | |
Permisos de la clave | Lee y desencripta datos encriptados. | Sin acceso |
No hay permisos para la clave | Lee los datos encriptados. | Sin acceso |
Si un usuario tiene permiso para acceder a la clave KMS y tiene acceso al conjunto de claves unido, las funciones de SQL pueden desunir el conjunto de claves y desencriptar el texto cifrado. Los usuarios también pueden usar la API de REST o la CLI de Cloud KMS para separar el conjunto de claves.
En la siguiente consulta de muestra, se usan funciones de SQL de KMS para desencriptar el texto cifrado no determinista:
SELECT AEAD.DECRYPT_STRING( KEYS.KEYSET_CHAIN(@kms_resource_name, @first_level_keyset), ciphertext, additional_authenticated_data) FROM ciphertext_table WHERE ...
Ejemplo de caso de uso
Supongamos una implementación en la que los códigos postales se consideran información sensible. Los datos de código postal se pueden insertar en la tabla de BigQuery mediante la función de encriptación AEAD, lo que encripta la columna Zipcode
. En este ejemplo, usamos la función AEAD.ENCRYPT
con la función de administración de conjunto de claves unida. La función KEYS.KEYSET_CHAIN
encripta la clave de encriptación digital con la KEK, y la función AEAD.ENCRYPT
pasa la información a KMS.
La cadena de conjunto de claves para la encriptación y desencriptación garantiza que la clave de encriptación de datos (DEK) esté encriptada o unida con una KEK y se pase con esa KEK. La DEK unida se desencripta o se separa dentro de la función de SQL y, luego, se usa para encriptar o desencriptar los datos.
La función no determinista AEAD puede desencriptar datos cuando se accede a ella mediante la función en la consulta que se ejecuta en la tabla.
La función determinista AEAD puede desencriptar datos cuando se accede a ella mediante la función en la consulta que se ejecuta en la tabla y admite la agregación y uniones mediante los datos encriptados.
Sintaxis de funciones no deterministas
La sintaxis compatible para usar funciones no deterministas incluye lo siguiente:
AEAD.ENCRYPT( KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset), plaintext, additional_authenticated_data)
AEAD.DECRYPT_STRING( KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset), ciphertext, additional_authenticated_data)
AEAD.DECRYPT_BYTES( KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset), ciphertext, additional_authenticated_data)
Consulta AEAD.DECRYPT_BYTES
, AEAD.ENCRYPT
, AEAD.DECRYPT_STRING
y KEYS.KEYSET_CHAIN
.
Sintaxis de las funciones deterministas
La sintaxis compatible para usar funciones deterministas incluye lo siguiente:
DETERMINISTIC_ENCRYPT( KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset), plaintext, additional_data)
DETERMINISTIC_DECRYPT_STRING( KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset), ciphertext, additional_data)
DETERMINISTIC_DECRYPT_BYTES( KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset), ciphertext, additional_data)
Consulta DETERMINISTIC_DECRYPT_BYTES
, DETERMINISTIC_ENCRYPT
, DETERMINISTIC_DECRYPT_STRING
y KEYS.KEYSET_CHAIN
.
Roles y permisos
Para obtener una lista de roles para Cloud KMS, consulta Permisos y roles de Cloud KMS.
Limitaciones
La encriptación con Cloud KMS tiene las siguientes limitaciones y restricciones:
Las claves de Cloud KMS están restringidas a la misma región o multirregión que la consulta. El uso de claves globales de Cloud KMS no está permitido por motivos de confiabilidad.
No es posible rotar un conjunto de claves unido con la función
KEYS.ROTATE_KEYSET
.En la actualidad, los parámetros constantes en una consulta de BigQuery son visibles para los usuarios en el plan de consultas de diagnóstico. Esto puede afectar los parámetros
kms_resource_name
yfirst_level_keyset
de la funciónKEYSET_CHAIN
. Las claves nunca se exponen en texto sin formato, y se requiere el permiso para la clave de Cloud KMS a fin de desencriptar el conjunto de claves unidos. Esto garantiza que las claves no se expongan a través del plan de consulta de diagnóstico, a menos que el usuario tenga permiso para desencriptar el conjunto de claves.La encriptación a nivel de columna tiene las siguientes limitaciones cuando se usa con clasificaciones de seguridad basadas en tipos:
Seguridad a nivel de columna: los usuarios solo pueden desencriptar o encriptar datos en columnas a las que pueden acceder.
Seguridad a nivel de fila: Los usuarios solo pueden desencriptar datos en las filas a las que pueden acceder.
Las funciones de SQL a nivel de columna no tienen un impacto significativo en el rendimiento en comparación con el rendimiento de las funciones de encriptación sin procesar en las que los datos clave se envían en texto simple.
Antes de comenzar
Para trabajar con claves de Cloud KMS, conjuntos de claves, tablas encriptadas, funciones deterministas y no deterministas, debes hacer lo siguiente si aún no lo hiciste:
Crea una clave de Cloud KMS para una columna encriptada con el nivel de protección de software o Módulo de seguridad de hardware (HSM).
Otorga permisos de usuario para trabajar con claves, encriptación y desencriptación de Cloud KMS.
Ten en cuenta los siguientes conceptos, ya que se hace referencia a ellos en las siguientes secciones:
PROJECT_ID
: El nombre del proyecto de Google Cloud.DATASET_NAME
: El nombre del conjunto de datos de BigQueryLOCATION_ID
: La ubicación del conjunto de datos de BigQuery.TABLE_NAME
: El nombre de la tabla de BigQuery.KEY_RING_ID
: El nombre del llavero de claves de Cloud KMS.KEY_ID
: El nombre de la clave de Cloud KMS.KMS_KEY
: La clave de Cloud KMS (KEK) en este formato:'gcp-kms://projects/PROJECT_ID/locations/LOCATION_ID/keyRings/KEY_RING_ID/cryptoKeys/KEY_ID'
Aquí hay un ejemplo de una clave de Cloud KMS:
'gcp-kms://projects/myProject/locations/us/keyRings/myKeyRing/cryptoKeys/myKeyName'
KMS_KEY_SHORT
: similar aKMS_KEY
, pero en este formato:projects/PROJECT_ID/locations/LOCATION_ID/keyRings/KEY_RING_ID/cryptoKeys/KEY_ID
KEYSET_DECODED
: Un conjunto de claves decodificado como una secuenciaBYTES
. El resultado es similar al de un conjunto de claves unidas decodificadas.Aunque las funciones de conjunto de claves muestran conjuntos de claves como bytes, el resultado del usuario se muestra como una cadena codificada. Para convertir un conjunto de claves codificado en un conjunto de claves decodificado, consulta Cómo decodificar un conjunto de claves de Cloud KMS.
KEYSET_ENCODED
: Un conjunto de claves codificadas comoSTRING
. El resultado es similar al de un conjunto de claves unidas codificadas.Para convertir un conjunto de claves codificado en un conjunto de claves decodificado, consulta Cómo decodificar un conjunto de claves de Cloud KMS.
WRAPPED_KEYSET_DECODED
: Un conjunto de claves unidos, decodificados como una secuenciaBYTES
. Este es un ejemplo de cómo se ve el resultado:b'\x0a$\x00\xa6\xee\x12Y\x8d|l"\xf7\xfa\xc6\xeafM\xdeefy\xe9\x7f\xf2z\xb3M\ xf6"\xd0\xe0Le\xa8\x8e\x0fR\xed\x12\xb7\x01\x00\xf0\xa80\xbd\xc1\x07Z\\ \xd0L<\x80A0\x9ae\xfd(9\x1e\xfa\xc8\x93\xc7\xe8\...'
Aunque las funciones de conjunto de claves unidas muestran conjuntos de claves unidos como bytes, el resultado del usuario se muestra como una cadena codificada. Para convertir un conjunto de claves unidas codificadas en un conjunto de claves unidos, consulta Cómo decodificar un conjunto de claves de Cloud KMS.
WRAPPED_KEYSET_ENCODED
: Un conjunto de claves unidos y codificado comoSTRING
Este es un ejemplo de cómo se ve el resultado:'CiQApu4SWTozQ7lNwITxpEvGlo5sT2rv1tyuSv3UAMtoTq/lhDwStwEA8KgwvX7CpVVzhWWMkRw WZNr3pf8uBIlzHeunCy8ZsQ6CofQYFpiBRBB6k/QqATbiFV+3opnDk/6dBL/S8OO1WoDC+DdD9 uzEFwqt5D20lTXCkGWFv1...'
Para convertir un conjunto de claves unidas codificadas en un conjunto de claves unidos, consulta Cómo decodificar un conjunto de claves de Cloud KMS.
Administración de claves
En las siguientes secciones, se incluyen tareas comunes que puedes realizar con las claves de Cloud KMS.
Crea un conjunto de claves
Puedes crear conjuntos de claves unidas o conjuntos de claves sin procesar. Para ello, completa los pasos en las siguientes secciones.
Crea un conjunto de claves sin procesar
Ejecuta la siguiente consulta para crear un conjunto de claves con una clave de tipo DETERMINISTIC_AEAD_AES_SIV_CMAC_256
.
SELECT KEYS.NEW_KEYSET('DETERMINISTIC_AEAD_AES_SIV_CMAC_256') AS raw_keyset
Crear un conjunto de claves unidas
Ejecuta la siguiente consulta para crear un conjunto de claves unidas de Cloud KMS con una clave de tipo DETERMINISTIC_AEAD_AES_SIV_CMAC_256
.
SELECT KEYS.NEW_WRAPPED_KEYSET( KMS_KEY, 'DETERMINISTIC_AEAD_AES_SIV_CMAC_256')
Decodificar un conjunto de claves
Aunque las funciones de SQL que muestran conjuntos de claves producen los conjuntos de claves en formato BYTES
, el resultado que muestra el usuario está codificado y se muestra en formato STRING
. Si deseas convertir esta cadena codificada en una secuencia de bytes decodificados que puedes usar como funciones de encriptación de claves literales, usa la siguiente consulta:
Decodificar un conjunto de claves unidas
Ejecuta la siguiente consulta para decodificar un conjunto de claves unidas de Cloud KMS.
SELECT FORMAT('%T', FROM_BASE64(WRAPPED_KEYSET_ENCODED'))
Decodificar un conjunto de claves sin procesar
Ejecuta la siguiente consulta para decodificar un conjunto de claves sin procesar.
SELECT FORMAT('%T', FROM_BASE64(KEYSET_ENCODED'))
Vuelve a unir un conjunto de claves unidas
Ejecuta la siguiente consulta para volver a unir un conjunto de claves unidos de Cloud KMS con una clave de Cloud KMS nueva. KMS_KEY_CURRENT
representa el KMS_KEY
nuevo que se usa para encriptar el conjunto de claves. KMS_KEY_NEW
representa el KMS_KEY
nuevo que se usa para encriptar el conjunto de claves.
SELECT KEYS.REWRAP_KEYSET( KMS_KEY_CURRENT, KMS_KEY_NEW, WRAPPED_KEYSET_DECODED)
Rota un conjunto de claves unidas.
Ejecuta la siguiente consulta para rotar un conjunto de claves unido a Cloud KMS con una clave de tipo DETERMINISTIC_AEAD_AES_SIV_CMAC_256
.
SELECT KEYS.ROTATE_WRAPPED_KEYSET( KMS_KEY, WRAPPED_KEYSET_DECODED, 'DETERMINISTIC_AEAD_AES_SIV_CMAC_256')
Genera un conjunto de claves sin procesar a partir de un conjunto de claves unidas
Algunas funciones de encriptación requieren un conjunto de claves sin procesar. Para desencriptar un conjunto de claves unidas de Cloud KMS a fin de producir un conjunto de claves sin procesar, completa los siguientes pasos.
En la herramienta de línea de comandos de bq, ingresa los siguientes comandos para guardar un conjunto de claves unido en un archivo llamado
keyset_to_unwrap
, desencriptar el conjunto de claves unido y producir el resultado en formatoKEYSET_DECODED
:echo WRAPPED_KEYSET_ENCODED | base64 -d > /tmp/decoded_wrapped_key
gcloud kms decrypt \ --ciphertext-file=/tmp/decoded_wrapped_key \ --key=KMS_KEY_SHORT \ --plaintext-file=/tmp/keyset_to_unwrap.dec \ --project=PROJECT_ID
od -An --format=o1 /tmp/keyset_to_unwrap.dec | tr ' ' '\'
Genera un conjunto de claves unido a partir de un conjunto de claves sin procesar
Algunas funciones de encriptación requieren un conjunto de claves unidas de Cloud KMS. Si deseas encriptar un conjunto de claves sin procesar para producir un conjunto de claves unidas, completa los siguientes pasos.
En la herramienta de línea de comandos de bq, ingresa los siguientes comandos para guardar un conjunto de claves sin procesar en un archivo llamado
keyset_to_wrap
, encriptar su conjunto de claves sin procesar y producir el resultado en formatoWRAPPED_KEYSET_DECODED
:echo KEYSET_ENCODED | base64 -d > /tmp/decoded_key
gcloud kms encrypt \ --plaintext-file=/tmp/decoded_key \ --key=KMS_KEY_SHORT \ --ciphertext-file=/tmp/keyset_to_wrap.dec \ --project=PROJECT_ID
od -An --format=o1 /tmp/keyset_to_wrap.dec | tr ' ' '\'
Genera una clave unida para una función de DLP
Para las funciones de DLP, necesitas una clave criptográfica y, luego, usarla para obtener una clave unida.
Para generar una clave criptográfica nueva, en la línea de comandos, ejecuta el siguiente comando. El tamaño de la clave puede ser de 16, 24 o 32 bytes. En el siguiente ejemplo, se usa una clave de 16 bytes:
openssl rand 16 > rand.key.16.bin
Une la clave de 16 bytes generada con una clave de KMS. Consulta el siguiente ejemplo:
KEYRING=projects/myproject/locations/us/keyRings/kms-test KEY=projects/myproject/locations/us/keyRings/kms-test/cryptoKeys/test-Kek PROJECT="myproject" gcloud kms encrypt --project $PROJECT --location us --keyring $KEYRING --key $KEY --plaintext-file ./rand.key.16.bin --ciphertext-file ./rand.key.16.wrapped
Ahora puedes obtener el literal
BYTES
de la clave unida o el formato base64 de la clave unida.Literal de bytes
username:~/tmp$ od -b ./rand.key.16.wrapped | cut -d ' ' -f 2- | head -n -1 | sed -e 's/^/ /' | tr ' ' '\'
El resultado luce de la siguiente manera:
\012\044\000\325\155\264\153\246\071\172\130\372\305\103\047\342\356\061\077\014\030\126\147\041\126\150\012\036\020\202\215\044\267\310\331\014\116\233\022\071\000\363\344\230\067\274\007\340\273\016\212\151\226\064\200\377\303\207\103\147\052\267\035\350\004\147\365\251\271\133\062\251\246\152\177\017\005\270\044\141\211\116\337\043\035\263\122\340\110\333\266\220\377\247\204\215\233
Formato base64
username:~/tmp$ base64 ./rand.key.16.wrapped
El resultado luce de la siguiente manera:
CiQA1W20a6Y5elj6xUMn4u4xPwwYVmchVmgKHhCCjSS3yNkMTpsSOQDz5Jg3vAfguw6KaZY0gP/Dh0NnKrcd6ARn9am5WzKppmp/DwW4JGGJTt8jHbNS4EjbtpD/p4SNmw==
Obtén la cantidad de claves de un conjunto de claves
Ejecuta la siguiente consulta para obtener la cantidad de claves en un conjunto de claves sin procesar.
Si trabajas con un conjunto de claves unidas, primero genera un conjunto de claves sin procesar.
Ejecuta esta consulta con el conjunto de claves sin procesar:
SELECT KEYS.KEYSET_LENGTH(KEYSET_DECODED) as key_count;
Obtener una representación JSON de un conjunto de claves
Ejecuta la siguiente consulta para ver una representación JSON de un conjunto de claves sin procesar.
Si trabajas con un conjunto de claves unidas, primero genera un conjunto de claves sin procesar.
Ejecuta esta consulta con el conjunto de claves sin procesar:
SELECT KEYS.KEYSET_TO_JSON(KEYSET_DECODED);
Encriptación y desencriptación
Puedes usar conjuntos de claves sin procesar o conjuntos de claves unidas para encriptar una columna de una tabla. También puedes optar por usar la encriptación determinista o no determinista en tus columnas. En los ejemplos de esta sección, se usan conjuntos de claves unidas, pero podrías reemplazarlos con conjuntos de claves sin procesar.
Encripta de forma determinista una columna con un conjunto de claves unido
Ejecuta la siguiente consulta para crear una tabla y almacenar un conjunto de claves unidos de Cloud KMS con encriptación determinista en una columna llamada encrypted_content
.
Encripta una columna con el conjunto de claves unidas.
CREATE OR REPLACE TABLE DATASET_NAME.TABLE_NAME AS SELECT DETERMINISTIC_ENCRYPT( KEYS.KEYSET_CHAIN(KMS_KEY, WRAPPED_KEYSET_DECODED), 'plaintext', '') AS encrypted_content
Desencripta de una forma determinista una columna con un conjunto de claves unidos
Ejecuta la siguiente consulta para desencriptar una columna con contenido encriptado de manera determinista mediante un conjunto de claves unidos a Cloud KMS. En esta consulta, se supone que haces referencia a una tabla con una columna llamada encrypted_content
.
SELECT DETERMINISTIC_DECRYPT_STRING( KEYS.KEYSET_CHAIN(KMS_KEY, WRAPPED_KEYSET_DECODED), encrypted_content, '') FROM DATASET_NAME.TABLE_NAME
Desencripta de forma no determinista una columna con un conjunto de claves unidos
Consulta Encripta de forma determinante una columna con un conjunto de claves unidas, pero reemplaza DETERMINISTIC_ENCRYPT
por AEAD.ENCRYPT
. Asegúrate de que tu conjunto de claves sea del tipo AEAD_AES_GCM_256
.
Desencripta de forma no determinista una columna con un conjunto de claves unidas
Consulta Desencripta de manera determinista una columna con un conjunto de claves unidas, pero reemplaza DETERMINISTIC_DECRYPT_STRING
por AEAD.DECRYPT_STRING
. Asegúrate de que tu conjunto de claves sea del tipo AEAD_AES_GCM_256
.
¿Qué sigue?
- Obtén más información sobre Cloud KMS. En este tema, se incluye información conceptual sobre la encriptación a nivel de columnas para Google Cloud.
- Obtén más información sobre la encriptación AEAD para BigQuery. En este tema, se incluye información conceptual sobre la encriptación a nivel de columnas específica para BigQuery.
- Obtén más información sobre las funciones de encriptación AEAD para BigQuery. Este tema contiene todas las funciones de SQL que puedes usar para la encriptación a nivel de columna en BigQuery.