En esta página se describe cómo implementar el cifrado del lado del cliente en Cloud SQL.
Información general
El cifrado del lado del cliente consiste en cifrar los datos antes de escribirlos en Cloud SQL. Puedes encriptar los datos de Cloud SQL de forma que solo tu aplicación pueda desencriptarlos.
Para habilitar el cifrado del lado del cliente, tienes las siguientes opciones:
- Usar una clave de cifrado almacenada en Cloud Key Management Service (Cloud KMS).
- Usar una clave de cifrado almacenada de forma local en tu aplicación.
En este documento, se describe cómo usar la primera opción, que es la que ofrece la gestión de claves más fluida. Creamos una clave de cifrado en Cloud KMS e implementamos el cifrado de envolvente mediante Tink,la biblioteca de cifrado de código abierto de Google.
¿Por qué necesitas el cifrado del lado del cliente?
Necesitas el cifrado del lado del cliente si quieres proteger los datos de Cloud SQL a nivel de columna. Imagina que tienes una tabla con nombres y números de tarjetas de crédito. Quieres conceder acceso a esta tabla a un usuario, pero no quieres que vea los números de las tarjetas de crédito. Puedes cifrar los números mediante el cifrado del lado del cliente. Mientras no se conceda acceso a la clave de cifrado en Cloud KMS, el usuario no podrá leer la información de la tarjeta de crédito.
También puede restringir el acceso a nivel de instancia o de base de datos.
Crear claves con Cloud KMS
Cloud KMS te permite crear y gestionar claves en Google Cloud.
Cloud KMS admite muchos tipos de claves diferentes. Para el cifrado del lado del cliente, debes crear una clave simétrica.
Para dar acceso a tu aplicación a la clave de Cloud KMS, debes conceder a la cuenta de servicio que usa tu aplicación el rol cloudkms.cryptoKeyEncrypterDecrypter
. En gcloud CLI, usa el siguiente comando para hacerlo:
gcloud kms keys add-iam-policy-binding key \ --keyring=key-ring \ --location=location \ --member=serviceAccount:service-account-name@example.domain.com \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
Aunque puedes usar la clave de KMS para cifrar datos directamente, aquí vamos a usar una solución más flexible llamada cifrado envolvente. Esto nos permite cifrar mensajes de más de 64 KB, que es el tamaño máximo de mensaje que puede admitir la API de Cloud Key Management Service.
Cifrado de envolvente de Cloud KMS
En el cifrado de envolvente, la clave de KMS actúa como clave de cifrado de claves (KEK). Es decir, se usa para cifrar las claves de cifrado de datos (DEK), que a su vez se usan para cifrar los datos reales.
Después de crear una KEK en Cloud KMS, para cifrar cada mensaje, debes hacer lo siguiente:
- Genera una clave de cifrado de datos (DEK) de forma local.
- Usa esta DEK de forma local para cifrar el mensaje.
- Llama a Cloud KMS para encriptar (envolver) la DEK con la KEK.
- Almacena los datos cifrados y la DEK envuelta.
En lugar de implementar el cifrado envolvente desde cero, en este documento usamos Tink.
Tink
Tink es una biblioteca multiplataforma y multilingüe que proporciona APIs criptográficas de alto nivel. Para cifrar datos con el cifrado envolvente de Tink, debes proporcionar a Tink un URI de clave que apunte a tu KEK en Cloud KMS y credenciales que permitan a Tink usar la KEK. Tink genera la DEK, encripta los datos, encapsula la DEK y devuelve un solo texto cifrado con los datos encriptados y la DEK encapsulada.
Tink admite el cifrado de envolvente en C++, Java, Go y Python mediante la API AEAD:
public interface Aead{
byte[] encrypt(final byte[] plaintext, final byte[] associatedData)
throws…
byte[] decrypt(final byte[] ciphertext, final byte[] associatedData)
throws…
}
Además del argumento normal de mensaje o texto cifrado, los métodos de cifrado y descifrado admiten datos asociados opcionales. Este argumento se puede usar para vincular el texto cifrado a un fragmento de datos. Por ejemplo, supongamos que tiene una base de datos con un campo user-id
y un campo encrypted-medical-history
. En este caso, el campo
user-id
probablemente debería usarse como datos asociados al cifrar el historial médico. De esta forma, un atacante no puede transferir el historial médico de un usuario a otro. También se usa para verificar que tienes la fila de datos correcta cuando ejecutas una consulta.
Ejemplos
En esta sección, veremos un ejemplo de código de una base de datos de información para votantes que usa el cifrado del lado del cliente. En el código de ejemplo se muestra cómo hacer lo siguiente:
- Crear una tabla de base de datos y un grupo de conexiones
- Configurar Tink para el cifrado envolvente
- Encriptar y desencriptar datos con el cifrado envolvente de Tink con una KEK en Cloud KMS
Antes de empezar
Crea una instancia de Cloud SQL siguiendo estas instrucciones. Anota la cadena de conexión, el usuario de la base de datos y la contraseña de la base de datos que crees.
Crea una base de datos para tu aplicación siguiendo estas instrucciones. Anota el nombre de la base de datos.
Crea una clave de KMS para tu aplicación siguiendo estas instrucciones. Copia el nombre de recurso de la clave que has creado.
Crea una cuenta de servicio con los permisos "Cliente de Cloud SQL" siguiendo estas instrucciones.
Añade el permiso "Encargado de cifrar o descifrar claves de CryptoKey de Cloud KMS" a tu cuenta de servicio siguiendo estas instrucciones.