Cette page explique comment mettre en œuvre le chiffrement côté client sur Cloud SQL.
Présentation
Le chiffrement côté client consiste à chiffrer les données avant de les écrire dans Cloud SQL. Vous pouvez chiffrer les données Cloud SQL de manière à ce que seule votre application puisse les déchiffrer.
Pour activer le chiffrement côté client, vous disposez des options suivantes :
- Utiliser une clé de chiffrement stockée dans Cloud Key Management Service (Cloud KMS).
- Utiliser une clé de chiffrement stockée localement dans votre application.
Dans cette rubrique, nous expliquons comment utiliser la première option, qui constitue l'option la plus fluide pour gérer les clés. Nous allons créer une clé de chiffrement dans Cloud KMS et mettre en œuvre le chiffrement encapsulé à l'aide de Tink, la bibliothèque de cryptographie Open Source de Google.
Pourquoi avez-vous besoin d'un chiffrement côté client ?
Vous avez besoin d'un chiffrement côté client pour protéger les données Cloud SQL au niveau de la colonne 1. Imaginons que vous avez une table de noms et de numéros de carte de crédit. Vous souhaitez autoriser un utilisateur à accéder à cette table, mais vous ne voulez pas qu'il puisse consulter les numéros de carte de crédit. Vous pouvez chiffrer les numéros de carte à l'aide du chiffrement côté client. Tant que l'utilisateur n'est pas autorisé à accéder à la clé de chiffrement dans Cloud KMS, il ne peut pas consulter les informations de carte de paiement.
Créer des clés à l'aide de Cloud KMS
Cloud KMS vous permet de créer et gérer des clés sur Google Cloud Platform.
Cloud KMS est compatible avec de nombreux types de clés différents. Pour le chiffrement côté client, vous devez créer une clé symétrique.
Pour permettre à votre application d'accéder à la clé dans Cloud KMS, vous devez attribuer le rôle cloudkms.cryptoKeyEncrypterDecrypter
au compte de service utilisé par votre application. Pour ce faire, dans gcloud, vous exécutez la commande suivante :
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
Même si vous pouvez utiliser la clé KMS pour chiffrer directement des données, nous utilisons ici une solution plus flexible appelée chiffrement encapsulé. Cela nous permet de chiffrer les messages de plus de 64 Ko, ce qui est la taille de message maximale acceptée par l'API Cloud Key Management Service.
Chiffrement encapsulé Cloud KMS
Dans le chiffrement encapsulé, la clé KMS agit en tant que clé de chiffrement de clé (KEK, Key Encryption Key). En d'autres termes, elle sert à chiffrer les clés de chiffrement des données (DEK, Data Encryption Key), qui elles-mêmes sont utilisées pour chiffrer les données proprement dites.
Après avoir créé une KEK dans Cloud KMS, pour chiffrer chaque message, vous devez effectuer les opérations suivantes :
- Générez une clé de chiffrement de données (DEK) en local.
- Utilisez cette DEK localement pour chiffrer le message.
- Appelez Cloud KMS pour chiffrer (encapsuler) la DEK avec la KEK.
- Stockez les données chiffrées et la DEK encapsulée.
Plutôt que de mettre en œuvre le chiffrement encapsulé en partant de zéro, dans cet article, nous utilisons Tink.
Tink
Tink est une bibliothèque multiplate-forme et compatible avec plusieurs langages, qui fournit des API de chiffrement de haut niveau. Pour chiffrer des données avec le chiffrement encapsulé de Tink, vous devez fournir à Tink un URI de clé pointant vers votre KEK dans Cloud KMS, ainsi que des identifiants qui permettent à Tink d'utiliser la KEK. Tink génère la DEK, chiffre les données, encapsule la DEK et renvoie un texte chiffré unique représentant les données chiffrées et la DEK encapsulée.
Tink permet de réaliser le chiffrement encapsulé en C++, Java, Go et Python à l'aide de l'API AEAD :
public interface Aead{
byte[] encrypt(final byte[] plaintext, final byte[] associatedData)
throws…
byte[] decrypt(final byte[] ciphertext, final byte[] associatedData)
throws…
}
Outre l'argument standard du message/texte chiffré, les méthodes de chiffrement et de déchiffrement permettent de traiter des données associées facultatives. Cet argument peut être utilisé pour lier le texte chiffré à un élément de données. Par exemple, supposons que vous avez une base de données comportant un champ user-id
et un champ encrypted-medical-history
. Dans ce cas, le champ user-id
doit probablement être utilisé en tant que données associées lors du chiffrement de l'historique médical. Cela permet de s'assurer qu'un pirate informatique ne peut pas transférer l'historique médical d'un utilisateur à un autre. Cela permet également de vérifier que vous disposez de la bonne ligne de données lorsque vous exécutez une requête.
Exemples
Dans cette section, nous allons parcourir un exemple de code pour une base de données d'informations sur les électeurs utilisant le chiffrement côté client. L'exemple de code montre comment :
- créer une table de base de données et un pool de connexions ;
- configurer Tink pour le chiffrement encapsulé ;
- chiffrer et déchiffrer des données à l'aide du chiffrement encapsulé de Tink avec une KEK hébergée dans Cloud KMS.
Avant de commencer
Créez une instance Cloud SQL en suivant ces instructions. Notez la chaîne de connexion, l'utilisateur de base de données et le mot de passe de base de données que vous créez.
Créez une base de données pour votre application en suivant ces instructions. Notez le nom de la base de données.
Créez une clé KMS pour votre application en suivant ces instructions. Copiez le nom de ressource de la clé créée.
Créez un compte de service avec les autorisations "Client Cloud SQL" en suivant ces instructions.
Ajoutez à votre compte de service l'autorisation "Chiffreur/Déchiffreur de CryptoKeys Cloud KMS" pour la clé en suivant ces instructions.
Créer un pool de connexions et créer une table dans la base de données.
Java
Python
Initialiser une primitive d'encapsulation AEAD avec Tink.
Java
Python
Chiffrer les données et les insérer dans la base de données.
Java
Python
Interroger la base de données et déchiffrer les données stockées.
Java
Python
-
Vous pouvez également restreindre l'accès au niveau de l'instance ou de la base de données. ↩