Auf dieser Seite wird beschrieben, wie die clientseitige Verschlüsselung in Cloud SQL implementiert wird.
Übersicht
Bei der clientseitigen Verschlüsselung werden Daten vor dem Schreiben in Cloud SQL verschlüsselt. Sie können Cloud SQL-Daten so verschlüsseln, dass nur Ihre Anwendung sie entschlüsseln kann.
Zum Aktivieren der clientseitigen Verschlüsselung haben Sie folgende Möglichkeiten:
- Mit einem im Cloud Key Management Service (Cloud KMS) gespeicherten Verschlüsselungsschlüssel.
- Mit einem lokal in Ihrer Anwendung gespeicherten Verschlüsselungsschlüssel.
In diesem Thema wird beschrieben, wie Sie die erste Option verwenden, die die einfachste Möglichkeit zur Schlüsselverwaltung bietet. Wir erstellen einen Verschlüsselungsschlüssel in Cloud KMS und implementieren die Umschlagverschlüsselung mithilfe von Tink, der Open-Source-Kryptografiebibliothek von Google.
Warum ist eine clientseitige Verschlüsselung erforderlich?
Sie benötigen clientseitige Verschlüsselung, wenn Sie die Cloud SQL-Daten auf Spaltenebene 1 schützen möchten. Angenommen, Sie haben eine Tabelle mit Namen und Kreditkartennummern. Sie möchten einem Nutzer Zugriff auf diese Tabelle gewähren, er soll jedoch nicht die Kreditkartennummern sehen. Sie können die Nummern mit der clientseitigen Verschlüsselung verschlüsseln. Solange dem Nutzer kein Zugriff auf den Verschlüsselungsschlüssel in Cloud KMS gewährt wurde, kann er die Kreditkartendaten nicht lesen.
Schlüssel mit Cloud KMS erstellen
Mit Cloud KMS können Sie Schlüssel auf der Google Cloud Platform erstellen und verwalten.
Cloud KMS unterstützt viele verschiedene Schlüsseltypen. Für die clientseitige Verschlüsselung müssen Sie einen symmetrischen Schlüssel erstellen.
Um Ihrer Anwendung Zugriff auf den Schlüssel in Cloud KMS zu gewähren, müssen Sie dem Dienstkonto, das Ihre Anwendung verwendet, die Rolle cloudkms.cryptoKeyEncrypterDecrypter
zuweisen. In gcloud verwenden Sie den folgenden Befehl:
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
Sie können den KMS-Schlüssel zwar verwenden, um Daten direkt zu verschlüsseln, hier verwenden wir aber eine flexiblere Lösung namens Umschlagverschlüsselung. Auf diese Weise können Nachrichten, die länger als 64 KB sind, verschlüsselt werden. Dies ist die maximale Nachrichtengröße, die von der Cloud Key Management Service API unterstützt wird.
Cloud KMS-Umschlagverschlüsselung
Bei der Umschlagverschlüsselung fungiert der KMS-Schlüssel als KEK. Das heißt, er wird zum Verschlüsseln von Datenverschlüsselungsschlüsseln (Data Encryption Keys, DEKs) verwendet, die wiederum zum Verschlüsseln tatsächlicher Daten verwendet werden.
Nachdem Sie einen KEK in Cloud KMS erstellt haben, müssen Sie zum Verschlüsseln jeder Nachricht Folgendes tun:
- Generieren Sie lokal einen Datenverschlüsselungsschlüssel (Data Encryption Key, DEK).
- Verwenden Sie diesen DEK lokal zum Verschlüsseln der Nachricht.
- Rufen Sie Cloud KMS auf, um den DEK mit dem KEK zu verschlüsseln (zusammenzufassen).
- Speichern Sie die verschlüsselten Daten und den zusammengefassten DEK.
In diesem Thema verwenden wir Tink, statt eine völlig neue Umschlag-Verschlüsselung zu implementieren.
Tink
Tink ist eine plattformübergreifende mehrsprachige Bibliothek, die hochwertige kryptografische APIs bereitstellt. Um Daten mit der Umschlagverschlüsselung von Tink zu verschlüsseln, stellen Sie Tink einen Schlüssel-URI bereit, der auf Ihren KEK in Cloud KMS verweist, und Anmeldedaten, mit denen Tink den KEK verwenden kann. Tink generiert den DEK, verschlüsselt die Daten, verpackt den DEK und gibt einen einzelnen Geheimtext mit den verschlüsselten Daten und dem verpackten DEK zurück.
Tink unterstützt die Umschlagverschlüsselung in C++, Java, Go und Python mithilfe der AEAD API:
public interface Aead{
byte[] encrypt(final byte[] plaintext, final byte[] associatedData)
throws…
byte[] decrypt(final byte[] ciphertext, final byte[] associatedData)
throws…
}
Neben dem normalen Argument „message/ciphertext” unterstützen die Methoden zum Verschlüsseln und Entschlüsseln optional verknüpfte Daten. Dieses Argument kann verwendet werden, um den Geheimtext mit einem Datenelement zu verknüpfen. Angenommen, Sie haben eine Datenbank mit dem Feld user-id
und dem Feld encrypted-medical-history
. In diesem Fall sollte das Feld user-id
beim Verschlüsseln des medizinischen Verlaufs als verknüpfte Daten verwendet werden. Dadurch wird verhindert, dass ein Angreifer einen medizinischen Verlauf von einem Nutzer zu einem anderen verschieben kann. Außerdem wird bei der Ausführung einer Abfrage überprüft, ob Sie die richtige Datenzeile haben.
Beispiele
In diesem Abschnitt wird anhand eines Beispielcodes eine Wählerdatenbank mit clientseitiger Verschlüsselung verwendet. Der Beispielcode zeigt, wie Pub/Sub-Ereignisse in einem Dienst gelesen werden, der in Cloud Run (vollständig verwaltet) bereitgestellt wird.
- Datenbanktabelle und Verbindungspool erstellen
- Tink für die Umschlagverschlüsselung einrichten
- Daten mithilfe der Umschlagverschlüsselung von Tink mit einem KEK in Cloud KMS verschlüsseln und entschlüsseln
Hinweis
Erstellen Sie mithilfe dieser Anleitung eine Cloud SQL-Instanz. Notieren Sie den Verbindungsstring, den Datenbanknutzer und das Datenbankpasswort, das Sie erstellen.
Erstellen Sie eine Datenbank für Ihre Anwendung. Folgen Sie dazu dieser Anleitung. Notieren Sie sich den Namen der Datenbank.
Erstellen Sie entsprechend dieser Anleitung einen KMS-Schlüssel für Ihre Anwendung. Kopieren Sie den Ressourcennamen des erstellten Schlüssels.
Erstellen Sie ein Dienstkonto mit den „Cloud SQL-Client”-Berechtigungen, indem Sie dieser Anleitung folgen.
Fügen Sie Ihrem Dienstkonto die Berechtigung "Cloud KMS CryptoKey-Verschlüsseler/Entschlüsseler" für den Schlüssel hinzu. Folgen Sie dazu dieser Anleitung.
Erstellen Sie einen Verbindungspool und eine neue Tabelle in der Datenbank.
Java
Python
Initialisieren Sie eine Umschlag-AEAD-Primitive mit Tink.
Java
Python
Verschlüsseln Sie Daten und fügen Sie sie in die Datenbank ein.
Java
Python
Fragen Sie die Datenbank ab und entschlüsseln Sie die gespeicherten Daten.
Java
Python
-
Sie können den Zugriff auch auf Instanz- oder Datenbankebene beschränken. ↩