In dieser Anleitung wird gezeigt, wie Sie eine Anwendung erstellen, die mit der Cloud KMS API (Cloud Key Management Service) kommuniziert, um Inhalte zu verschlüsseln, die in einem Memorystore for Redis-Speicher in Google Cloud gespeichert sind. Weitere Informationen zu den in dieser Anleitung verwendeten Konzepten finden Sie im Dokument zu dieser Anleitung: Verschlüsselung auf Anwendungsebene: Memorystore for Redis.
Diese Anleitung richtet sich an Anwendungsentwickler und Sicherheitsexperten, die mit Google Cloud, Linux, Schlüsselverwaltungsdiensten, Redis, Git, Maven und Java vertraut sind.
Die Anleitung ist inkrementell strukturiert, ähnlich wie eine testbasierte Entwicklungsmethode. Zuerst führen Sie einen Test aus. Anschließend führen Sie eine Änderung ein, die zum Fehlschlagen des Tests führt. Zum Schluss entfernen Sie den Testfehler.
Ziele
- Sie können ein Paar von Memorystore for Redis-Instanzen erstellen und testen.
- Daten konvertieren und in Redis laden
- Erstellen Sie Ihr eigenes Schlüsselverwaltungssystem (KMS).
- Weitere Informationen zur Verwaltung von Verschlüsselungsschlüsseln
Kosten
In dieser Anleitung werden die folgenden kostenpflichtigen Komponenten von Google Cloud verwendet:
Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Neuen Google Cloud-Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.
Nach Abschluss dieser Anleitung können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.
Hinweis
-
Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.
-
Die Abrechnung für das Cloud-Projekt muss aktiviert sein. So prüfen Sie, ob die Abrechnung für Ihr Projekt aktiviert ist.
- Compute Engine, Cloud KMS, and Memorystore for Redis APIs aktivieren.
-
Aktivieren Sie Cloud Shell in der Cloud Console.
VM-Instanz für das Projekt erstellen
Richten Sie in Cloud Shell die Konfiguration des
gcloud
-Befehlszeilentools ein:gcloud config set project PROJECT_NAME gcloud config set compute/zone us-central1-f gcloud config set compute/region us-central1
Ersetzen Sie PROJECT_NAME durch den Namen Ihres Google Cloud-Projekts für diese Anleitung.
VM-Instanz erstellen:
gcloud compute instances create ale-instance \ --machine-type=n1-standard-1 \ --image-family=debian-10 \ --image-project=debian-cloud \ --boot-disk-size=200GB
Klicken Sie in der Nutzerkonsole auf der Seite "VM-Instanzen" auf SSH, um sich bei Ihrer VM-Instanz anzumelden.
Ein neues Fenster wird geöffnet, das in dieser Anleitung das Projektfenster genannt wird (im Gegensatz zum Cloud Shell-Fenster). Um einige Schritte der Anleitung auszuführen, müssen Sie zwischen dem Projektfenster und dem Cloud Shell-Fenster wechseln.
Git und Maven installieren
Installieren Sie im Projektfenster Git und Maven:
sudo apt-get install git wget maven
Möglicherweise wird folgende Warnung angezeigt:
E: Could not get lock /var/lib/dpkg/lock
Dieser Fehler kann auftreten, wenn die VM-Startskripts noch ausgeführt werden. Wenn Sie diesen Fehler erhalten, warten Sie ein bis zwei Minuten und führen Sie dann den vorherigen Befehl noch einmal aus.
Java Development Kit (JDK) installieren
Ändern Sie im Projektfenster das Verzeichnis:
cd /tmp
Laden Sie das Java-Installationspaket herunter:
wget https://download.java.net/java/GA/jdk14.0.1/664493ef4a6946b186ff29eb326336a2/7/GPL/openjdk-14.0.1_linux-x64_bin.tar.gz
Die Ausgabe sieht etwa so aus:
--2020-05-17 19:21:39-- https://download.java.net/java/GA/jdk14.0.1/664493ef4a6946b186ff29eb326336a2/7/GPL/openjdk-14.0.1_linux-x64_bin.tar.gz Resolving download.java.net (download.java.net)... 23.213.168.108 Connecting to download.java.net (download.java.net)|23.213.168.108|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 198665889 (189M) [application/x-gzip] Saving to: 'openjdk-14.0.1_linux-x64_bin.tar.gz' oenjdk-14.0.1_linux-x64_ 80%[======================> ] 151.72M 4.86MB/s eta 8s
Rufen Sie den Inhalt des Verzeichnisses "Java Virtual Machine (JVM)" auf:
ls /usr/lib/jvm/
Die Ausgabe sollte in etwa so aussehen:
ls: /usr/lib/jvm/: No such file or directory
Diese Ausgabe gibt an, dass der Ordner nicht existiert. Erstellen Sie in diesem Fall den Ordner:
sudo mkdir /usr/lib/jvm
JDK installieren:
cd /usr/lib/jvm sudo tar xzf /tmp/openjdk-14.0.1_linux-x64_bin.tar.gz export JAVA_HOME=/usr/lib/jvm/jdk-14.0.1/
Klonen des tinkCryptoHelper-Repositorys
In den folgenden Schritten klonen Sie das Code-Repository für tinkCryptoHelper, die in dieser Anleitung verwendete Java-Anwendung.
Wechseln Sie im Projektfenster zu Ihrem Basisverzeichnis:
cd ~
Klonen Sie die Codebasis "tinkCryptoHelper":
git clone https://github.com/google/tinkCryptoHelper.git cd tinkCryptoHelper
Build der tinkCryptoHelper-Anwendung erstellen
In den folgenden Schritten verwenden Sie das mvn
-Tool, um Ihren ersten tinkCryptoHelper-Build aus dem Java-Quellcode in ein ausführbares Java-Paket zu machen.
Erstellen Sie im Projektfenster das Paket:
mvn package
Die Ausgabe endet mit:
[INFO] -------------------------------------------------------------------- [INFO] BUILD SUCCESS [INFO] -------------------------------------------------------------------- [INFO] Total time: 13.880 s [INFO] Finished at: 2020-05-17T19:29:13+00:00 [INFO] Final Memory: 19M/116M [INFO] --------------------------------------------------------------------
Das System testen
In den folgenden Abschnitten führen Sie Tests durch, um zu testen, wie sich das System nach Änderungen an der Konfiguration verhält. Es gibt 14 Integrationstests im Code im Repository. Bei jedem Test wird ein anderes Verhalten getestet, um sicherzustellen, dass das System korrekt funktioniert. Die Tests sind abhängig von der Konfiguration. Wenn zum Beispiel keine Redis-Datenbank mit dem System verknüpft ist, versuchen die Tests nicht, die Redis-Konnektivität zu testen.
Grundlegende Funktionstests
Nachdem Sie einen tinkCryptoHelper-Build erstellt haben, können Sie seine grundlegende Funktionalität testen. Sie haben keine Redis-Datenbank online, sodass die Konnektivitätstests nicht fehlschlagen.
Führen Sie im Projektfenster einen Test aus:
mvn test
Die Ausgabe sieht etwa so aus:
[INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running com.google.samples.kms.ale.AppTest AES256_GCM encryption cipherlength: 64 Envelope encryption cipherlength: 224 [INFO] Tests run: 14, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.057 s - in com.google.samples.kms.ale.AppTest [INFO] [INFO] Results: [INFO] [INFO] Tests run: 14, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] -------------------------------------------------------------------- [INFO] BUILD SUCCESS [INFO] -------------------------------------------------------------------- [INFO] Total time: 7.087 s [INFO] Finished at: 2020-05-17T19:34:21+00:00 [INFO] Final Memory: 12M/56M
Das wichtige Ergebnis ist
Tests run: 14, Failures: 0, Errors: 0, Skipped: 0
. Diese Ausgabe zeigt an, dass alle Tests erfolgreich ausgeführt wurden.
Redis-Verbindung ohne Instanzen testen
Im nächsten Schritt für vollständige Integrationstests muss die Anwendung (tinkCryptoHelper) mit Redis kommunizieren. Die Anwendung ruft die Redis-Verbindungsstring-Informationen aus der Datei prefs.xml
ab. Als Teil des ersten Tests, den Sie im vorherigen Abschnitt ausgeführt haben, erstellte die tinkCryptoHelper-Anwendung an verschiedenen Speicherorten mehrere prefs.xml
-Dateien gemäß der Klassenstruktur des Java-Quellcodes.
Als Übung setzen Sie redisIsOnline
in der Datei prefs.xml
auf true
. Die Redis-Instanz ist nicht online, weil Sie sie noch erstellen müssen. Dieser Test führt dazu, dass die Konnektivitätstests fehlschlagen.
Listen Sie im Projektfenster die XML-Dateien in der Quellcodestruktur auf, damit Sie die richtige
prefs.xml
-Datei finden und bearbeiten können:find ~/.java -name '*.xml'
Die Ausgabe sieht etwa so aus:
/home/USERNAME/.java/.userPrefs/com/google/samples/kms/ale/prefs.xml /home/USERNAME/.java/.userPrefs/com/google/samples/kms/prefs.xml /home/USERNAME/.java/.userPrefs/com/google/samples/prefs.xml /home/USERNAME/.java/.userPrefs/com/google/prefs.xml /home/USERNAME/.java/.userPrefs/com/prefs.xml
In dieser Ausgabe ist
USERNAME
der Nutzername, mit dem Sie sich angemeldet haben.Um sich auf das Testen von Redis mit Maven vorzubereiten, öffnen Sie die folgende Datei mit
nano
(oder einem anderen UNIX-Editor wievi
):nano ~/.java/.userPrefs/com/google/samples/kms/ale/prefs.xml
Der Inhalt dieser Konfigurationsdatei sieht etwa so aus:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE map SYSTEM "http://java.sun.com/dtd/preferences.dtd"> <map MAP_XML_VERSION="1.0"> <entry key="com.google.samples.kms.ale.AppTest" value="true"/> </map>
Fügen Sie im Abschnitt
map
der Konfigurationsdatei einen zweiten Eintrag hinzu:<entry key="redisIsOnline" value="true"/>
Der Abschnitt
map
sieht jetzt etwa so aus:<map MAP_XML_VERSION="1.0"> <entry key="com.google.samples.kms.ale.AppTest" value="true"/> <entry key="redisIsOnline" value="true"/> </map>
Speichern und schließen Sie die Datei.
Test ausführen:
mvn test
Da Redis nicht online ist, enthält die Ausgabe ähnliche Fehler wie diese:
[ERROR] AppTest.testRedis3_2:86 » JedisConnection Failed connecting to host 127.0.0.2:... [ERROR] AppTest.testRedis4_0:79 » JedisConnection Failed connecting to host 127.0.0.1:... [ERROR] AppTest.testRedisRoundtripRedis3_2:93->testRedisRoundtripRedisSeries:105->testRedisRoundtripClear:149 » JedisConnection [ERROR] AppTest.testRedisRoundtripRedis4_0:99->testRedisRoundtripRedisSeries:105->testRedisRoundtripClear:149 » JedisConnection [INFO]
Sie haben für einen Fehler gesorgt. Im nächsten Abschnitt beheben Sie den Fehler.
Redis-Instanzen erstellen
Im vorherigen Schritt ist der Test fehlgeschlagen, weil es keine Redis-Instanz gab, zu der eine Verbindung hergestellt werden konnte. Sie müssen nun Redis-Instanzen erstellen, um dies zu korrigieren. Für Tests mit der tinkCryptoHelper-Anwendung benötigen Sie zwei Redis-Instanzen unterschiedlicher Releaseversionen. Die Tests werden auf beiden Instanzen ausgeführt.
Redis-Instanzen erstellen
Erstellen Sie in Cloud Shell zwei Redis-Instanzen unterschiedlicher Versionen:
gcloud redis instances create redis32 --redis-version redis_3_2 --region us-central1 gcloud redis instances create redis40 --redis-version redis_4_0 --region us-central1
Das Erstellen der Redis 3.2- und Redis 4.0-Instanzen dauert einige Minuten.
Rufen Sie Informationen zu den Instanzen auf:
gcloud redis instances list --region us-central1
Die Ausgabe sieht etwa so aus:
INSTANCE_NAME VERSION REGION TIER SIZE_GB HOST PORT NETWORK RESERVED_IP STATUS CREATE_TIME redis32 REDIS_3_2 us-central1 BASIC 1 10.126.141.179 6379 default 10.126.141.176/29 READY 2020-05-17T19:47:15 redis40 REDIS_4_0 us-central1 BASIC 1 10.55.16.163 6379 default 10.55.16.160/29 READY 2020-05-17T19:50:44
Kopieren Sie die IP-Adressen aus der Ausgabe. Sie benötigen die Host-IP-Adressen in den nächsten Schritten.
IP-Adressen für Redis-Instanzen konfigurieren
Der nächste Schritt besteht darin, der tinkCryptoHelper-Anwendung mitzuteilen, wo die Redis-Instanzen zu finden sind.
Öffnen Sie im Projektfenster die zuvor geöffnete Datei
prefs.xml
:nano ~/.java/.userPrefs/com/google/samples/kms/ale/prefs.xml
Fügen Sie im Abschnitt
map
der Konfigurationsdatei zwei Zeilen nach dem Eintrag hinzu, den Sie zuvor hinzugefügt haben:<entry key="redisHost3_2" value="IP_ADDRESS3.2" /> <entry key="redisHost4_0" value="IP_ADDRESS4.0" />
Dabei gilt:
IP_ADDRESS3.2
: Wert der zuvor kopiertenredis32
-InstanzIP_ADDRESS4.0
: Wert der zuvor kopiertenredis40
-Instanz
Speichern und schließen Sie die Datei.
Test ausführen:
mvn test
Die Ausgabe sieht etwa so aus:
Set of 5000 cleartext values took on average 2µs on host 10.126.141.179 Get of 5000 cleartext values took on average 1µs on host 10.126.141.179 Set of 5000 encrypted values took on average 40µs on host 10.126.141.179 ... Envelope encryption cipherlength: 224 [INFO] Tests run: 14, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 8.312 s - in com.google.samples.kms.ale.AppTest [INFO] [INFO] Results: [INFO] [INFO] Tests run: 14, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 12.470 s [INFO] Finished at: 2020-05-17T20:55:46+00:00 [INFO] Final Memory: 12M/56M [INFO] ------------------------------------------------------------------------
Sie haben den Integrationstest mit Redis erfolgreich abgeschlossen.
Daten konvertieren und in Redis laden
Im vorherigen Abschnitt hatten die Tests mehrere Nebenwirkungen, von denen eine war, dass Daten in die Redis-Instanzen eingefügt wurden. Dieser Vorgang war erforderlich, um die Integrationstests abzuschließen. Wenn Sie das System mit Ihren eigenen Daten testen möchten, zeigen die folgenden Schritte, wie Sie mit tinkCryptoHelper die Daten verschlüsseln und anschließend die Redis-Datenbank mit Ihren eigenen Daten aktualisieren. Das Git-Repository stellt die Beispieldatei data.csv
bereit, Sie können aber eine eigene Datei erstellen.
Erstellen Sie im Projektfenster eine JAR-Datei:
mvn assembly:single
Konvertieren Sie die Datei
data.csv
in eine Datei, die mit dem Redis-Befehlimport
kompatibel ist:$JAVA_HOME/bin/java -jar target/cryptoHelper-1.0-jar-with-dependencies.jar data.csv redis_import.txt
Die Datei
redis_import.txt
enthält eine Reihe von Befehlen, mit denen Sie Ihre Daten in Redis einfügen können.Installieren Sie die Redis-Tools, die eine Befehlszeile (CLI) enthalten:
sudo apt-get install redis-tools
Wenn Sie die vorhandenen Daten in der Redis-Datenbank nicht behalten möchten, können Sie so vorgehen:
Stellen Sie über die Redis-Befehlszeile eine Verbindung zu Redis her:
redis-cli -h IP_ADDRESS
Ersetzen Sie
IP_ADDRESS
durch eine der zuvor kopierten IP-Adressen.Löschen Sie die Daten in der Datenbank:
FLUSHALL exit
Laden Sie die Daten:
cat redis_import.txt | redis-cli -h IPADDRESS --pipe
Um zu testen, ob die Daten vorhanden sind, stellen Sie noch einmal eine Verbindung zu Redis her und rufen Sie den Schlüssel ab:
Stellen Sie eine Verbindung zu Redis her:
redis-cli -h IP_ADDRESS
Rufen Sie den Schlüssel ab:
get 1
Die Ausgabe sieht so aus:
Hello World
Wenn Sie Ihre eigenen Daten verwendet haben, unterscheiden sich der Schlüssel und der Wert wahrscheinlich.
Eigenen KMS erstellen
Der KMS-Verschlüsselungsschlüssel in dieser Anleitung gehört zu einem Google-eigenen Cloud-Projekt namens tink-test-infrastructure
und nicht zu dem von Ihnen erstellten Projekt. Dieses Beispielprojekt enthält einen KMS, mit dem der Verschlüsselungsschlüssel öffentlich verfügbar gemacht wird.
Um Ihre eigene KMS-Instanz und -Schlüssel zu erstellen, Sie erstellen ein Dienstkonto und verknüpfen es mit dem IAM-Rolle "Cloud KMS CryptoKey-Verschlüsseler/Entschlüsseler" (roles/cloudkms.cryptoKeyEncrypterDecrypter
). Mit dieser Rolle kann das Dienstkonto einen KMS-Schlüsselbund erstellen und Schlüssel hinzufügen.
Dienstkonto einrichten
Erstellen Sie in Cloud Shell ein neues Dienstkonto:
gcloud iam service-accounts create tink-509 \ --description="Account for KMS" \ --display-name="tinkAccount"
Rufen Sie in der Cloud Console die Seite IAM und Verwaltung auf:
Klicken Sie auf Hinzufügen und fügen Sie dann das Dienstkonto
tink-509
der Rolle Cloud KMS CryptoKey Verschlüsseler/Entschlüsseler hinzu.Speichern Sie die Änderung und verlassen Sie die Cloud Console.
Speichern Sie im Projektfenster eine JSON-Anmeldedatenschlüsseldatei für das neue Dienstkonto:
Sichern Sie die alte Anmeldedatenschlüsseldatei:
mv kmsServiceAccountCredentials.json kmsServiceAccountCredentials.json.old
Du musst dazu angemeldet sein. Führen Sie den Befehl aus und folgen Sie dann der OAuth-Anleitung:
gcloud config set project PROJECT_ID gcloud auth login
Ersetzen Sie
PROJECT_ID
durch Ihre Cloud-Projekt-ID.Erstellen Sie die neue Schlüsseldatei mit den Anmeldedaten:
gcloud iam service-accounts keys create kmsServiceAccountCredentials.json \ --iam-account tink-509@app-lev-enc.iam.gserviceaccount.com
Die Ausgabe sieht etwa so aus:
created key [c09dfea3892d6c309333f1998caf35845dc50608] of type [json] as [kmsServiceAccountCredentials.json] for [tink-509@app-lev-enc.iam.gserviceaccount.com]
Cloud KMS-Schlüsselbund und -Schlüssel erstellen
Erstellen Sie in Cloud Shell einen Cloud KMS-Schlüsselbund:
gcloud kms keyrings create "unit-and-integration-testing" --location "global" gcloud kms keys create aead-key --purpose=encryption --location "global" \ --keyring unit-and-integration-testing
Fügen Sie einer IAM-Richtlinie die IAM-Rolle
roles/cloudkms.cryptoKeyEncrypterDecrypter
hinzu:gcloud kms keys add-iam-policy-binding \ aead-key --location global --keyring unit-and-integration-testing \ --member serviceAccount:tink-509@app-lev-enc.iam.gserviceaccount.com \ --role roles/cloudkms.cryptoKeyEncrypterDecrypter
Mit dieser Rolle kann Ihr Dienstkonto auf die Schlüssel zugreifen.
Frühere Redis-Daten löschen
In den vorherigen Tests wurde die Redis-Datenbank mit Beispieldaten gefüllt. Die Verschlüsselung basierte jedoch auf einem älteren Schlüssel. Sie müssen die Daten löschen und den älteren Schlüssel löschen.
Listen Sie alle Redis-Instanzen in Cloud Shell auf:
gcloud redis instances list --region us-central1
Notieren Sie sich die IP-Adresse der von Ihnen erstellten Instanzen.
Stellen Sie eine Verbindung zu den beiden Redis-Instanzen her:
redis-cli -h IP_ADDRESS
Führen Sie den vorhergehenden Befehl zweimal aus und ersetzen Sie
IP_ADDRESS
durch die IP-Adresse für jede Instanz.Löschen Sie die Daten in der Datenbank:
FLUSHALL exit
Wenn Sie den endgültigen Test später in dieser Anleitung ausführen, werden die Daten in den Redis-Tabellen mit den neuen Schlüsseln verschlüsselt.
Angeben, wo tinkCryptoHelper das neue KMS findet
Öffnen Sie im Projektfenster die KMS-Datei
pref.xml
mit einem UNIX-Editor:nano ~/.java/.userPrefs/com/google/samples/kms/prefs.xml
Fügen Sie die folgende Zeile als zweiten Eintrag hinzu:
<entry key="keyResourceIdUri" value="gcp-kms://projects/PROJECT_ID/locations/global/keyRings/unit-and-integration-testing/cryptoKeys/aead-key"/>
Ersetzen Sie
PROJECT_ID
durch Ihre Cloud-Projekt-ID.
Abschließenden Test ausführen
Führen Sie im Projektfenster Tests aus:
mvn test
Die Ausgabe sieht etwa so aus:
... Envelope encryption cipherlength: 224 [INFO] Tests run: 14, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 8.312 s - in com.google.samples.kms.ale.AppTest ...
Sie haben das KMS und die Schlüssel erfolgreich erstellt und diese verwendet, um tinkCryptoHelper zu testen.
Bereinigen
Löschen Sie das Projekt, um zu vermeiden, dass Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen in Rechnung gestellt werden.
Projekt löschen
- Wechseln Sie in der Cloud Console zur Seite Ressourcen verwalten.
- Wählen Sie in der Projektliste das Projekt aus, das Sie löschen möchten, und klicken Sie dann auf Löschen.
- Geben Sie im Dialogfeld die Projekt-ID ein und klicken Sie auf Shut down (Beenden), um das Projekt zu löschen.