Freigeben über


Verwenden der clientseitigen Verschlüsselung mit Always Encrypted für Azure Cosmos DB

GILT FÜR: NoSQL

Wichtig

Mit dem Release 1.0 unserer Verschlüsselungspakete wurde ein Breaking Change eingeführt. Wenn Sie Datenverschlüsselungsschlüssel und verschlüsselungsfähige Container mit früheren Versionen erstellt haben, müssen Sie Ihre Datenbanken und Container nach der Migration Ihres Clientcodes zu 1.0-Paketen neu erstellen.

Always Encrypted ist eine Funktion zum Schutz sensibler Daten, wie Kreditkartennummern oder Personalausweisnummern (z. B. US-Sozialversicherungsnummern), die in Azure Cosmos DB gespeichert sind. Mit Always Encrypted können Clients, vertrauliche Daten innerhalb von Clientanwendungen verschlüsseln wobei die Verschlüsselungsschlüssel niemals an den Server weitergegeben werden.

Always Encrypted bietet clientseitige Verschlüsselungsfunktionen für Azure Cosmos DB. Die clientseitige Verschlüsselung Ihrer Daten kann in den folgenden Szenarien erforderlich sein:

  • Schützen vertraulicher Daten mit bestimmten Vertraulichkeitsmerkmalen: Always Encrypted ermöglicht Clients das Verschlüsseln vertraulicher Daten in ihren Anwendungen und gibt niemals die Nur-Text-Daten oder Verschlüsselungsschlüssel für den Azure Cosmos DB Dienst preis.
  • Implementieren der Zugriffssteuerung pro Eigenschaft: Da die Verschlüsselung mit Schlüsseln gesteuert wird, die Sie von Azure Key Vault besitzen und verwalten, können Sie Zugriffsrichtlinien anwenden, um zu steuern, auf welche sensiblen Eigenschaften jeder Client Zugriff hat.

Konzepte

Always Encrypted für Azure Cosmos DB führt einige neue Konzepte, die an der Konfiguration Ihrer clientseitigen Verschlüsselung beteiligt sind, ein.

Verschlüsselungsschlüssel

Datenverschlüsselungsschlüssel

Wenn Sie Always Encrypted einsetzen, werden Daten mit Datenverschlüsselungsschlüsseln ( Data Encryption Key, DEK) verschlüsselt, die im Voraus erstellt werden sollten. Diese DEKs werden im Azure Cosmos DB gespeichert und auf Datenbankebene definiert, sodass ein DEK über mehrere Container hinweg freigegeben werden kann. Die Erstellung der DEKs erfolgt clientseitig mithilfe des Azure Cosmos DB Software Development Kit.

Sie haben folgende Möglichkeiten:

  • Erstellen Sie einen DEK pro zu verschlüsselnden Eigenschaft, oder
  • Verwenden Sie denselben DEK, um mehrere Eigenschaften zu verschlüsseln.

Vom Kunden verwaltete Schlüssel

Bevor DEKs in einem Azure Cosmos DB gespeichert werden, werden sie von einem vom Kunden verwalteten Schlüssel (Customer-Managed Key, CMK) gepackt. Durch Steuern des Packens und Entpackens von DEKs steuern CMKs effektiv den Zugriff auf die Daten, die mit ihren entsprechenden DEKs verschlüsselt sind. Der CMK-Speicher ist erweiterbar mit einer Standardimplementierung konzipiert, die eine Speicherung in Azure Key Vault erwartet.

Verschlüsselungsschlüssel

Verschlüsselungsrichtlinie

Ähnlich wie bei einer Indizierungsrichtlinie ist eine Verschlüsselungsrichtlinie eine Spezifikation auf Containerebene, die beschreibt, wie JSON-Eigenschaften verschlüsselt werden sollen. Diese Richtlinie muss bereitgestellt werden, wenn der Container erstellt wird und unveränderlich ist. In der aktuellen Version können Sie die Verschlüsselungsrichtlinie nicht aktualisieren.

Für jede Eigenschaft, die Sie verschlüsseln möchten, definiert die Verschlüsselungsrichtlinie Folgendes:

  • Der Pfad der Eigenschaft in Form von /property. Derzeit werden nur Pfade der obersten Ebene unterstützt, geschachtelte Pfade wie /path/to/property werden nicht unterstützt.
  • Die ID des DEK, der beim Verschlüsseln und Entschlüsseln der Eigenschaft verwendet wird.
  • Ein Verschlüsselungstyp. Dieser kann entweder randomisiert oder deterministisch sein.
  • Der Verschlüsselungsalgorithmus, der beim Verschlüsseln der Eigenschaft verwendet wird. Der angegebene Algorithmus kann den beim Erstellen des Schlüssels definierten Algorithmus überschreiben, wenn sie kompatibel sind.

Zufällige im Vergleich zu deterministischer Verschlüsselung

Der Azure Cosmos DB Dienst erkennt nie den Nur-Text von Eigenschaften, die mit Always Encrypted verschlüsselt sind. Er unterstützt jedoch weiterhin einige Abfragefunktionen für die verschlüsselten Daten, abhängig vom Verschlüsselungstyp, der für eine Eigenschaft verwendet wird. Always Encrypted unterstützt die folgenden zwei Verschlüsselungstypen:

  • Bei der deterministischen Verschlüsselung wird immer derselbe verschlüsselte Wert für einen gegebenen Nur-Textwert und eine gegebene Verschlüsselungskonfiguration generiert. Mithilfe der deterministischen Verschlüsselung können Abfragen Gleichheitsfilter für verschlüsselte Eigenschaften ausgeführt werden. Es kann Angreifern jedoch ermöglichen, Informationen zu verschlüsselten Werten zu erraten, indem sie die Muster in der verschlüsselten Eigenschaft untersuchen. Dies gilt besonders, wenn es sich um einen kleinen Satz möglicher verschlüsselter Werte handelt, beispielsweise WAHR/FALSCH, oder die Regionen „Nord“/ „Süd“/ „Ost“/ „West“.

  • Randomisierte Verschlüsselung: arbeitet mit einer Methode, die Daten auf weniger vorhersagbare Weise verschlüsselt. Die zufällige Verschlüsselung ist sicherer, verhindert jedoch, dass Abfragen auf verschlüsselte Eigenschaften gefiltert werden können.

Weitere Informationen zur deterministischen und zufälligen Verschlüsselung in Always Encrypted finden Sie unter Generieren des Initialisierungsvektors (IV).

Einrichten von Azure Key Vault

Der erste Schritt um mit Always Encrypted zu beginnen besteht im Erstellen Ihrer CMKs in Azure Key Vault:

  1. Erstellen einer neue Azure Key Vault-Instanz, oder navigieren zu einer vorhandenen Instanz.
  2. Erstellen Sie im Abschnitt Schlüssel einen neuen Schlüssel.
  3. Navigieren Sie nach dem Erstellen des Schlüssels zu seiner aktuellen Version, und kopieren Sie den vollständigen Schlüsselbezeichner:
    https://<my-key-vault>.vault.azure.net/keys/<key>/<version>. Wenn Sie die Schlüsselversion am Ende des Schlüsselbezeichners weglassen, wird die neueste Version des Schlüssels verwendet.

Als Nächstes müssen Sie konfigurieren, wie das Azure Cosmos DB SDK auf Ihre Azure Key Vault zugreifen soll. Diese Authentifizierung erfolgt über eine Microsoft Entra-Identität. Höchstwahrscheinlich verwenden Sie die Identität einer Microsoft Entra-Anwendung oder einer verwalteten Identität als Proxy zwischen Ihrem Clientcode und Ihrer Azure Key Vault-Instanz, obwohl jede Art von Identität verwendet werden kann. Führen Sie die folgenden Schritte aus, um Ihre Microsoft Entra-Identität als Proxy zu verwenden:

  1. Wechseln Sie von Ihrer Azure Key Vault-Instanz zum Abschnitt Zugriffsrichtlinien, und fügen Sie eine neue Richtlinie hinzu:

    1. Wählen Sie unter Schlüsselberechtigungendie Optionen Abrufen, Liste, Schlüssel entpacken, Schlüssel verpacken, Bestätigen und Abmeldenaus.
    2. Suchen Sie unter Prinzipal auswählen nach Ihrer Microsoft Entra-Identität.

Schützen Ihres CMK vor versehentlichem Löschen

Um sicherzustellen, dass Sie nach dem versehentlichen Löschen Ihres CMK nicht den Zugriff auf Ihre verschlüsselten Daten verlieren, wird empfohlen, zwei Eigenschaften für Ihre Azure Key Vault-Instanz zu setzen: vorläufiges Löschen und Löschschutz.

Wenn Sie eine neue Azure Key Vault-Instanz erstellen, aktivieren Sie diese Eigenschaften während der Erstellung:

Screenshot: Eigenschaften für vorläufiges Löschen und Bereinigungsschutz für eine neue Azure Key Vault-Instanz

Bei Verwendung einer vorhandenen Azure Key Vault-Instanz können Sie überprüfen, ob diese Eigenschaften aktiviert sind, indem Sie sich im Azure-Portal den Abschnitt Eigenschaften ansehen. Ist eine dieser Eigenschaften nicht aktiviert, finden Sie in den Abschnitten „Aktivieren des vorläufigen Löschens“ und „Aktivieren des Bereinigungsschutzes“ in einem der folgenden Artikel weitere Informationen:

Initialisieren des SDK

Hinweis

Always Encrypted für Azure Cosmos DB wird aktuell unterstützt:

Für die Verwendung von Always Encrypted, muss eine Instanz von KeyResolver an Ihre Azure Cosmos DB SDK-Instanz angefügt werden. Diese im Azure.Security.KeyVault.Keys.Cryptography-Namespace definierte Klasse wird für die Interaktion mit dem Schlüsselspeicher verwendet, der Ihre CMKs hostet.

Die folgenden Codeausschnitte verwenden die DefaultAzureCredential-Klasse zum Abrufen der Microsoft Entra-Identität, die beim Zugriff auf Ihre Azure Key Vault-Instanz verwendet werden soll. Beispiele für das Erstellen verschiedenartiger TokenCredential-Klassen finden Sie hier.

Hinweis

Sie benötigen das Azure.Identity-Zusatzpaket, um auf die TokenCredential-Klassen zuzugreifen.

var tokenCredential = new DefaultAzureCredential();
var keyResolver = new KeyResolver(tokenCredential);
var client = new CosmosClient("<connection-string>")
    .WithEncryption(keyResolver, KeyEncryptionKeyResolverName.AzureKeyVault);

Erstellen eines Datenverschlüsselungsschlüssel

Bevor Daten in einem Container verschlüsselt werden können, muss ein Datenverschlüsselungsschlüssel in der übergeordneten Datenbank erstellt werden.

Das Erstellen eines neuen Datenverschlüsselungsschlüssels erfolgt durch Aufrufen der CreateClientEncryptionKeyAsync-Methode und Übergeben folgender Angaben:

  • Eine Zeichenfolgenerkennung, die den Schlüssel in der Datenbank eindeutig identifiziert.
  • Der Verschlüsselungsalgorithmus, der mit dem Schlüssel verwendet werden soll. Derzeit wird nur ein Algorithmus unterstützt.
  • Der Schlüsselbezeichner des in Azure Key Vault gespeicherten CMK. Dieser Parameter wird in einem generischen EncryptionKeyWrapMetadata-Objekt übergeben. Dabei gilt:
    • type definiert den Typ der Schlüsselauflösung (z. B. Azure Key Vault).
    • name kann ein beliebiger Anzeigename sein.
    • value muss der Schlüsselbezeichner sein.

    Wichtig

    Navigieren Sie nach Erstellen des Schlüssels zur aktuellen Version, und kopieren Sie den vollständigen Schlüsselbezeichner: https://<my-key-vault>.vault.azure.net/keys/<key>/<version>. Wenn Sie die Schlüsselversion am Ende des Schlüsselbezeichners weglassen, wird die neueste Version des Schlüssels verwendet.

    • algorithm definiert, welcher Algorithmus als Wrapper für den Schlüsselverschlüsselungsschlüssels mit dem kundenseitig verwalteten Schlüssel verwendet werden soll.
var database = client.GetDatabase("my-database");
await database.CreateClientEncryptionKeyAsync(
    "my-key",
    DataEncryptionAlgorithm.AeadAes256CbcHmacSha256,
    new EncryptionKeyWrapMetadata(
        KeyEncryptionKeyResolverName.AzureKeyVault,
        "akvKey",
        "https://<my-key-vault>.vault.azure.net/keys/<key>/<version>",
        EncryptionAlgorithm.RsaOaep.ToString()));

Erstellen eines Containers mit einer Verschlüsselungsrichtlinie

Geben Sie beim Erstellen des Containers die Verschlüsselungsrichtlinie auf der Containerebene an.

var path1 = new ClientEncryptionIncludedPath
{
    Path = "/property1",
    ClientEncryptionKeyId = "my-key",
    EncryptionType = EncryptionType.Deterministic.ToString(),
    EncryptionAlgorithm = DataEncryptionAlgorithm.AeadAes256CbcHmacSha256
};
var path2 = new ClientEncryptionIncludedPath
{
    Path = "/property2",
    ClientEncryptionKeyId = "my-key",
    EncryptionType = EncryptionType.Randomized.ToString(),
    EncryptionAlgorithm = DataEncryptionAlgorithm.AeadAes256CbcHmacSha256
};
await database.DefineContainer("my-container", "/partition-key")
    .WithClientEncryptionPolicy()
    .WithIncludedPath(path1)
    .WithIncludedPath(path2)
    .Attach()
    .CreateAsync();

Lesen und Schreiben verschlüsselter Daten

So werden Daten verschlüsselt

Jedes Mal, wenn ein Dokument in Azure Cosmos DB geschrieben wird, sucht das SDK nach der Verschlüsselungsrichtlinie, um herauszufinden, welche Eigenschaften verschlüsselt werden müssen und wie. Das Ergebnis der Verschlüsselung ist eine Base64-Zeichenfolge.

Verschlüsseln komplexer Typen:

  • Wenn die zu verschlüsselnde Eigenschaft ein JSON-Array ist, wird jeder Eintrag des Arrays verschlüsselt.

  • Wenn die zu verschlüsselnde Eigenschaft ein JSON-Objekt ist, werden nur die Blattwerte des Objekts verschlüsselt. Die dazwischenliegenden Untereigenschaftsnamen bleiben in Nur-Text-Form erhalten.

Lesen verschlüsselter Elemente

Es ist keine explizite Aktion erforderlich, um verschlüsselte Eigenschaften zu entschlüsseln, wenn Sie Punktlesevorgänge (Abrufen eines einzelnen Elements anhand seiner ID und seines Partitionsschlüssels), Abfragen oder das Lesen des Änderungsfeed durchführen. Der Grund ist wie folgt:

  • Das SDK sucht die Verschlüsselungsrichtlinie, um herauszufinden, welche Eigenschaften entschlüsselt werden müssen.
  • Das Ergebnis der Verschlüsselung bettet den ursprünglichen JSON-Typ des Werts ein.

Bitte beachten Sie, dass die Auflösung verschlüsselter Eigenschaften und deren nachfolgende Entschlüsselung nur auf den Ergebnissen basiert, die von Ihren Anforderungen zurückgegeben werden. Wenn beispielsweise property1 verschlüsselt ist, aber in property2 (SELECT property1 AS property2 FROM c) projiziert wird, wird es beim Empfangen durch das SDK nicht als verschlüsselte Eigenschaft identifiziert.

Filtern von Abfragen nach verschlüsselten Eigenschaften

Beim Schreiben von Abfragen, die nach verschlüsselten Eigenschaften filtern, muss eine bestimmte Methode verwendet werden, um den Wert des Abfrageparameters zu übergeben. Diese Methode verwendet die folgenden Argumente:

  • Der Name des Abfrageparameters.
  • Der Wert, der in der Abfrage verwendet werden soll.
  • Der Pfad der verschlüsselten Eigenschaft (wie in der Verschlüsselungsrichtlinie definiert).

Wichtig

Verschlüsselte Eigenschaften können nur in Gleichheitsfiltern (WHERE c.property = @Value) verwendet werden. Jede andere Verwendung gibt unvorhersehbare und falsche Abfrageergebnisse zurück. Diese Einschränkung wird in den nächsten Versionen des SDK besser durchgesetzt.

var queryDefinition = container.CreateQueryDefinition(
    "SELECT * FROM c where c.property1 = @Property1");
await queryDefinition.AddParameterAsync(
    "@Property1",
    1234,
    "/property1");

Lesen von Dokumenten, wenn nur eine Teilmenge der Eigenschaften entschlüsselt werden kann

In Situationen, in denen der Client nicht auf alle CMK-Elemente zugreifen kann, die zum Verschlüsseln von Eigenschaften verwendet werden, kann nur eine Teilmenge der Eigenschaften entschlüsselt werden, wenn die Daten zurückgelesen werden. Wenn beispielsweise property1 mit Schlüssel1 und property2 mit Schlüssel2 verschlüsselt wurde, kann eine Clientanwendung, die nur Zugriff auf Schlüssel1 hat, weiterhin Daten lesen, nicht aber property2. In diesem Fall müssen Sie Ihre Daten über SQL-Abfragen lesen und die Eigenschaften entfernen, die der Client nicht entschlüsseln kann: SELECT c.property1, c.property3 FROM c.

CMK-Drehung

Möglicherweise möchten Sie Ihren CMK „rotieren“ (d. h. einen neuen CMK anstelle des aktuellen CMK verwenden), wenn Sie vermuten, dass der aktuelle CMK kompromittiert wurde. Es ist auch eine gängige Sicherheitspraxis, den CMK regelmäßig zu rotieren. Um diese Rotation durchzuführen, müssen Sie nur den Schlüsselbezeichner des neuen CMK angeben, der zum Packen eines bestimmten DEK verwendet werden soll. Bitte beachten Sie, dass sich dieser Vorgang nicht auf die Verschlüsselung Ihrer Daten auswirkt, sondern auf den Schutz des DEK. Der Zugriff auf den vorherigen CMK sollte erst widerrufen werden, wenn die Rotation abgeschlossen ist.

await database.RewrapClientEncryptionKeyAsync(
    "my-key",
    new EncryptionKeyWrapMetadata(
        KeyEncryptionKeyResolverName.AzureKeyVault,
        "akvKey",
        "https://<my-key-vault>.vault.azure.net/keys/<new-key>/<version>",
        EncryptionAlgorithm.RsaOaep.ToString()));

DEK-Rotation

Eine Funktion für die Rotation eines Datenverschlüsselungsschlüssels (DEK) ist nicht direkt verfügbar. Dies liegt daran, dass für das Aktualisieren eines DEK eine Überprüfung aller Container erforderlich ist, in denen dieser Schlüssel verwendet wird, und alle Eigenschaften, die mit diesem Schlüssel verschlüsselt sind, neu verschlüsselt werden müssen. Dieser Vorgang kann nur clientseitig erfolgen, da der Azure Cosmos DB-Dienst den unverschlüsselten Wert des DEK nicht speichert und niemals darauf zugreift.

In der Praxis kann eine DEK-Rotation durchgeführt werden, indem eine Datenmigration von den betroffenen Containern zu neuen Containern durchgeführt wird. Die neuen Container können genauso wie die ursprünglichen Container erstellt werden. Um Sie bei einer solchen Datenmigration zu unterstützen, gibt es ein eigenständiges Migrationstool auf GitHub.

Hinzufügen zusätzlicher verschlüsselter Eigenschaften

Das Hinzufügen zusätzlicher verschlüsselter Eigenschaften zu einer vorhandenen Verschlüsselungsrichtlinie wird aus den gleichen Gründen, die im Abschnitt oben erläutert werden, nicht unterstützt. Dieser Vorgang erfordert eine vollständige Überprüfung des Containers, um sicherzustellen, dass alle Instanzen der Eigenschaften ordnungsgemäß verschlüsselt sind. Dieser Vorgang kann nur clientseitig ausgeführt werden. Wie bei einer DEK-Rotation kann das Hinzufügen zusätzlicher verschlüsselter Eigenschaften erfolgen, indem eine Datenmigration zu einem neuen Container mit einer entsprechenden Verschlüsselungsrichtlinie durchgeführt wird.

Wenn Sie flexibel sind, was das Hinzufügen neuer verschlüsselter Eigenschaften aus der Sicht des Schemas angeht, können Sie auch die Schemaunabhängigkeit von Azure Cosmos DB nutzen. Wenn Sie eine in Ihrer Verschlüsselungsrichtlinie definierte Eigenschaft als „Eigenschaftenbehälter“ verwenden, können Sie darunter uneingeschränkt weitere Eigenschaften hinzufügen. Angenommen, dass property1 in Ihrer Verschlüsselungsrichtlinie definiert ist, und Sie fügen zunächst property1.property2 in Ihre Dokumente ein. Wenn Sie zu einem späteren Zeitpunkt property3 als verschlüsselte Eigenschaft hinzufügen müssen, können Sie property1.property3 in Ihre Dokumente einfügen. Diese neue Eigenschaft wird ebenfalls automatisch verschlüsselt. Für diesen Ansatz ist keine Datenmigration erforderlich.

Nächste Schritte