Tutorial: Verschlüsseln und Entschlüsseln von Blobs mit Azure Key Vault

In diesem Tutorial erfahren Sie, wie Sie die clientseitige Verschlüsselung verwenden, um Blobs mithilfe eines in Azure Key Vault gespeicherten Schlüssels zu verschlüsseln und zu entschlüsseln.

Azure Blob Storage unterstützt sowohl dienstseitige als auch clientseitige Verschlüsselung. In den meisten Szenarien empfiehlt Microsoft die Verwendung von dienstseitigen Verschlüsselungsfeatures zum benutzerfreundlichen Schutz Ihrer Daten. Weitere Informationen zur dienstseitigen Verschlüsselung finden Sie unter Azure Storage-Verschlüsselung für ruhende Daten.

Die Azure Blob Storage-Clientbibliothek für .NET unterstützt die clientseitige Datenverschlüsselung innerhalb von Anwendungen vor dem Hochladen der Daten in Azure Storage sowie die Entschlüsselung von Daten während des Herunterladens auf den Client. Um eine Schlüsselverwaltung zu ermöglichen, unterstützt die Bibliothek zudem die Integration in Azure Key Vault.

Dieses Tutorial veranschaulicht folgende Vorgehensweisen:

  • Konfigurieren von Berechtigungen für eine Azure Key Vault-Ressource
  • Erstellen einer Konsolenanwendung für die Interaktion mit Ressourcen mithilfe von .NET-Clientbibliotheken
  • Hinzufügen eines Schlüssels zu einem Schlüsseltresor
  • Konfigurieren clientseitiger Verschlüsselungsoptionen mithilfe eines Schlüssels, der in einem Schlüsseltresor gespeichert ist
  • Erstellen eines Blobdienst-Clientobjekts mit aktivierter clientseitiger Verschlüsselung
  • Hochladen eines verschlüsselten Blobs und anschließendes Herunterladen und Entschlüsseln des Blobs

Voraussetzungen

Ihren Microsoft Entra-Benutzer*innen Rollen zuweisen

Stellen Sie beim lokalen Entwickeln sicher, dass das Benutzerkonto, das auf den Schlüsseltresor zugreift, die richtigen Berechtigungen hat. Sie benötigen die Rolle Kryptografiebeauftragter für Schlüsseltresore, um einen Schlüssel zu erstellen und Aktionen für Schlüssel in einem Schlüsseltresor auszuführen. Sie können einem Benutzer Azure RBAC-Rollen über das Azure-Portal, die Azure CLI oder mit Azure PowerShell zuweisen. Weitere Informationen zu den verfügbaren Bereichen für Rollenzuweisungen finden Sie auf der Seite Bereichsübersicht.

In diesem Szenario weisen Sie Ihrem Benutzerkonto Berechtigungen zu, die auf den Schlüsseltresor zugeschnitten sind, um dem Prinzip der geringsten Rechte zu folgen. Auf diese Weise erhalten Benutzer nur die erforderlichen Mindestberechtigungen, und es entstehen sicherere Produktionsumgebungen.

Das folgende Beispiel zeigt, wie Sie Ihrem Benutzerkonto die Rolle Kryptografiebeauftragter für Schlüsseltresore zuweisen, die den Zugriff bietet, den Sie für dieses Tutorial benötigen.

Wichtig

In den meisten Fällen dauert es eine oder zwei Minute(n), bis die Rollenzuweisung in Azure weitergegeben wird. In seltenen Fällen kann es aber bis zu acht Minuten dauern. Wenn bei der ersten Ausführung Ihres Codes Authentifizierungsfehler auftreten, warten Sie einige Momente, und versuchen Sie es dann erneut.

  1. Suchen Sie im Azure-Portal Ihren Schlüsseltresor mithilfe der Hauptsuchleiste oder der linken Navigationsleiste.

  2. Wählen Sie auf der Übersichtsseite des Schlüsseltresors im linken Menü die Option Zugriffssteuerung (IAM) aus.

  3. Wählen Sie auf der Seite Zugriffssteuerung (IAM) die Registerkarte Rollenzuweisungen aus.

  4. Wählen Sie im oberen Menü + Hinzufügen und aus dem dann angezeigten Dropdownmenü die Option Rollenzuweisung hinzufügen aus.

    Screenshot: Zuweisen einer Rolle im Azure-Portal

  5. Über das Suchfeld können Sie die Ergebnisse für die gewünschte Rolle filtern. Suchen Sie in diesem Beispiel nach Kryptografiebeauftragter für Schlüsseltresore, wählen Sie das entsprechende Ergebnis aus, und wählen Sie dann Weiter aus.

  6. Wählen Sie unter Zugriff zuweisen zu die Option Benutzer, Gruppe oder Dienstprinzipal und dann die Option + Mitglieder auswählen aus.

  7. Suchen Sie im Dialogfeld nach Ihrem Microsoft Entra-Benutzernamen (normalerweise Ihre E-Mail-Adresse benutzer@domäne), und wählen Sie unten im Dialogfeld Auswählen aus.

  8. Wählen Sie Überprüfen und zuweisen aus, um zur letzten Seite zu gelangen, und wählen Sie erneut Überprüfen und zuweisen aus, um den Vorgang abzuschließen.

Einrichten des Projekts

  1. Verwenden Sie in einem Konsolenfenster (z. B. PowerShell oder Bash) den Befehl dotnet new zum Erstellen einer neuen Konsolen-App mit dem Namen BlobEncryptionKeyVault. Dieser Befehl erstellt ein einfaches „Hallo Welt“-C#-Projekt mit einer einzigen Quelldatei: Program.cs.

    dotnet new console -n BlobEncryptionKeyVault
    
  2. Wechseln Sie zu dem neu erstellten Verzeichnis BlobEncryptionKeyVault.

    cd BlobEncryptionKeyVault
    
  3. Öffnen Sie das Projekt in Ihrem gewünschten Code-Editor. Zum Öffnen des Projekts in:

    • Visual Studio suchen Sie die Datei BlobEncryptionKeyVault.csproj, und doppelklicken Sie darauf.
    • Visual Studio Code führen Sie den folgenden Befehl aus:
    code .
    

Um in diesem Beispiel mit Azure-Diensten zu interagieren, installieren Sie mithilfe von dotnet add package die folgenden Clientbibliotheken:

dotnet add package Azure.Identity
dotnet add package Azure.Security.KeyVault.Keys
dotnet add package Azure.Storage.Blobs

Fügen Sie die folgenden using-Anweisungen hinzu, und stellen Sie sicher, dass Sie dem Projekt einen Verweis auf System.Configuration hinzufügen.

using Azure;
using Azure.Core;
using Azure.Identity;
using Azure.Security.KeyVault.Keys;
using Azure.Security.KeyVault.Keys.Cryptography;
using Azure.Storage;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Azure.Storage.Blobs.Specialized;

Festlegen von Umgebungsvariablen

Diese Anwendung sucht nach einer Umgebungsvariable namens KEY_VAULT_NAME, um den Namen Ihres Schlüsseltresors abzurufen. Öffnen Sie zum Festlegen der Umgebungsvariablen ein Konsolenfenster, und befolgen Sie die Anleitung für Ihr Betriebssystem. Ersetzen Sie <your-key-vault-name> durch den Namen Ihres Schlüsseltresors.

Windows:

Sie können Umgebungsvariablen für Windows über die Befehlszeile festlegen. Wenn Sie diesen Ansatz verwenden, sind die Werte jedoch für alle Anwendungen zugänglich, die unter diesem Betriebssystem ausgeführt werden. Dies kann Konflikte verursachen, wenn Sie nicht vorsichtig sind. Umgebungsvariablen können auf Benutzer- oder Systemebene festgelegt werden:

setx KEY_VAULT_NAME "<your-key-vault-name>"

Sie müssen nach dem Hinzufügen der Umgebungsvariablen unter Windows eine neue Instanz des Befehlsfensters öffnen. Wenn Sie Visual Studio unter Windows verwenden, müssen Sie es nach dem Erstellen der Umgebungsvariablen möglicherweise neu starten, damit die Änderung erkannt wird.

Linux:

export KEY_VAULT_NAME=<your-key-vault-name>

Hinzufügen eines Schlüssels in Azure Key Vault

In diesem Beispiel erstellen wir einen Schlüssel und fügen ihn mithilfe der Azure Key Vault-Clientbibliothek dem Schlüsseltresor hinzu. Sie können auch einen Schlüssel über die Azure CLI, das Azure-Portal oder PowerShell erstellen und einem Schlüsseltresor hinzufügen.

Im folgenden Beispiel erstellen wir ein KeyClient-Objekt für den angegebenen Tresor. Das KeyClient-Objekt wird dann verwendet, um einen neuen RSA-Schlüssel im angegebenen Tresor zu erstellen.

var keyName = "testRSAKey";
var keyVaultName = Environment.GetEnvironmentVariable("KEY_VAULT_NAME");

// URI for the key vault resource
var keyVaultUri = $"https://{keyVaultName}.vault.azure.net";

TokenCredential tokenCredential = new DefaultAzureCredential();

// Create a KeyClient object
var keyClient = new KeyClient(new Uri(keyVaultUri), tokenCredential);

// Add a key to the key vault
var key = await keyClient.CreateKeyAsync(keyName, KeyType.Rsa);

Erstellen von Schlüssel- und Schlüsselresolverinstanzen

Als Nächstes verwenden wir den Schlüssel, den wir soeben dem Tresor hinzugefügt haben, um die Kryptografieclient- und Schlüsselresolverinstanzen zu erstellen. CryptographyClient implementiert IKeyEncryptionKey und wird zum Ausführen von kryptografischen Vorgängen mit in Azure Key Vault gespeicherten Schlüsseln verwendet. KeyResolver implementiert IKeyEncryptionResolver, ruft Schlüsselverschlüsselungsschlüssel aus dem Schlüsselbezeichner ab und löst den Schlüssel auf.

// Cryptography client and key resolver instances using Azure Key Vault client library
CryptographyClient cryptoClient = keyClient.GetCryptographyClient(key.Value.Name, key.Value.Properties.Version);
KeyResolver keyResolver = new (tokenCredential);

Wenn Sie über einen vorhandenen Schlüssel im Tresor verfügen, den Sie für die Verschlüsselung verwenden möchten, können Sie die Schlüssel- und Schlüsselresolverinstanzen erstellen, indem Sie den URI übergeben:

var keyVaultKeyUri = $"https://{keyVaultName}.vault.azure.net/keys/{keyName}";
CryptographyClient cryptoClient = new CryptographyClient(new Uri(keyVaultKeyUri), tokenCredential);

Konfigurieren von Verschlüsselungsoptionen

Nun müssen wir die Verschlüsselungsoptionen konfigurieren, die für das Hochladen und Herunterladen von Blobs verwendet werden sollen. Um die clientseitige Verschlüsselung zu verwenden, erstellen Sie zunächst ein ClientSideEncryptionOptions-Objekt und legen es bei der Clienterstellung mit SpecializedBlobClientOptions fest.

Die Klasse ClientSideEncryptionOptions stellt die Clientkonfigurationsoptionen für die Verbindung mit Blob Storage mithilfe der clientseitigen Verschlüsselung bereit. KeyEncryptionKey ist für Uploadvorgänge erforderlich und wird zum Umschließen des generierten Inhaltsverschlüsselungsschlüssels verwendet. KeyResolver ist für Downloadvorgänge erforderlich und ruft den richtigen Schlüsselverschlüsselungsschlüssel ab, um den heruntergeladenen Inhaltsverschlüsselungsschlüssel zu entpacken. KeyWrapAlgorithm ist für Uploads erforderlich und gibt den Algorithmusbezeichner an, der beim Umschließen des Inhaltsverschlüsselungsschlüssels verwendet werden soll.

Wichtig

Aufgrund einer Sicherheitslücke in Version 1 wird empfohlen, das Objekt ClientSideEncryptionOptions mithilfe von ClientSideEncryptionVersion.V2_0 für den Versionsparameter zu erstellen. Weitere Informationen zum Entschärfen des Sicherheitsrisikos in Ihren Apps finden Sie unter Verringern der Sicherheitsrisiken in Ihren Anwendungen. Weitere Informationen zu dieser Sicherheitslücke finden Sie unter Azure Storage updating client-side encryption in SDK to address security vulnerability (Azure Storage aktualisiert clientseitige Verschlüsselung im SDK, um Sicherheitsrisiken zu beheben).

// Configure the encryption options to be used for upload and download
ClientSideEncryptionOptions encryptionOptions = new (ClientSideEncryptionVersion.V2_0)
{
    KeyEncryptionKey = cryptoClient,
    KeyResolver = keyResolver,
    // String value that the client library will use when calling IKeyEncryptionKey.WrapKey()
    KeyWrapAlgorithm = "RSA-OAEP"
};

// Set the encryption options on the client options.
BlobClientOptions options = new SpecializedBlobClientOptions() { ClientSideEncryption = encryptionOptions };

Konfigurieren des Clientobjekts für die Verwendung der clientseitigen Verschlüsselung

In diesem Beispiel wenden wir die clientseitigen Verschlüsselungskonfigurationsoptionen auf ein Objekt vom Typ BlobServiceClient an. Bei Anwendung auf Dienstclientebene werden diese Verschlüsselungsoptionen vom Dienstclient an Containerclients und von Containerclients an Blobclients übergeben. Wenn das BlobClient-Objekt einen Upload- oder Downloadvorgang ausführt, verwenden die Azure Blob Storage-Clientbibliotheken die Umschlagverschlüsselung, um Blobs auf der Clientseite zu verschlüsseln und zu entschlüsseln. Die Umschlagverschlüsselung verschlüsselt einen Schlüssel mit einem oder mehreren zusätzlichen Schlüsseln.

// Create a blob client with client-side encryption enabled.
// Attempting to construct a BlockBlobClient, PageBlobClient, or AppendBlobClient from a BlobContainerClient
// with client-side encryption options present will throw, as this functionality is only supported with BlobClient.
Uri blobUri = new (string.Format($"https://{accountName}.blob.core.windows.net"));
BlobClient blob = new BlobServiceClient(blobUri, tokenCredential, options).GetBlobContainerClient("test-container").GetBlobClient("testBlob");

Verschlüsseln des Blobs und Hochladen

Wenn das BlobClient-Objekt eine Uploadmethode aufruft, werden mehrere Schritte ausgeführt, um die clientseitige Verschlüsselung durchzuführen:

  1. Die Azure Storage-Clientbibliothek generiert einen zufälligen Initialisierungsvektor (IV) mit einer Größe von 16 Byte zusammen mit einem zufälligen Inhaltsverschlüsselungsschlüssel (Content Encryption Key, CEK) mit einer Größe von 32 Byte. Mithilfe dieser Informationen wird die Umschlagverschlüsselung der Blobdaten durchgeführt.
  2. Blobdaten werden mit diesem CEK verschlüsselt.
  3. Der CEK wird dann mit dem in ClientSideEncryptionOptions angegebenen Schlüsselverschlüsselungsschlüssel (Key Encryption Key, KEK) umschlossen (verschlüsselt). In diesem Beispiel ist der KEK ein asymmetrisches Schlüsselpaar, das in der angegebenen Azure Key Vault-Ressource gespeichert ist. Der Blobclient selbst hat nie Zugriff auf den KEK. Er ruft lediglich den Algorithmus für das Umschließen des Schlüssels auf, der von Key Vault bereitgestellt wird.
  4. Die verschlüsselten Blobdaten werden dann in das Speicherkonto hochgeladen.

Fügen Sie den folgenden Code hinzu, um ein Blob zu verschlüsseln und in Ihr Azure-Speicherkonto hochzuladen.

// Upload the encrypted contents to the blob
Stream blobContent = BinaryData.FromString("Ready for encryption, Captain.").ToStream();
await blob.UploadAsync(blobContent);

Nachdem das Blob hochgeladen wurde, können Sie das Blob in Ihrem Speicherkonto anzeigen, um den verschlüsselten Inhalt zusammen mit den Verschlüsselungsmetadaten anzuzeigen.

Entschlüsseln des Blobs und Herunterladen

Die Azure Storage-Clientbibliothek geht davon aus, dass der Benutzer den KEK entweder lokal oder in einem Schlüsseltresor verwaltet. Der Benutzer muss den spezifischen Schlüssel, der für die Verschlüsselung verwendet wurde, nicht kennen. Der in ClientSideEncryptionOptions angegebene Schlüsselresolver wird verwendet, um Schlüsselbezeichner aufzulösen, wenn Blobdaten heruntergeladen und entschlüsselt werden.

Wenn das BlobClient-Objekt eine Downloadmethode aufruft, werden mehrere Schritte ausgeführt, um die verschlüsselten Blobdaten zu entschlüsseln:

  1. Die Clientbibliothek lädt die verschlüsselten Blobdaten, einschließlich Verschlüsselungsmetadaten, aus dem Speicherkonto herunter.
  2. Der umschlossene CEK wird dann mithilfe des KEK entpackt (entschlüsselt). Die Clientbibliothek hat während dieses Prozesses keinen Zugriff auf den KEK, sondern ruft nur den in ClientSideEncryptionOptions angegebenen Schlüsselentpackungsalgorithmus auf. Der private Schlüssel des RSA-Schlüsselpaars verbleibt im Schlüsseltresor. Der verschlüsselte Schlüssel aus den Blobmetadaten, der den CEK enthält, wird daher zur Entschlüsselung an den Schlüsseltresor gesendet.
  3. Die Clientbibliothek verwendet den CEK, um die verschlüsselten Blobdaten zu entschlüsseln.

Fügen Sie den folgenden Code hinzu, um das zuvor hochgeladene Blob herunterzuladen und zu entschlüsseln.

// Download and decrypt the encrypted contents from the blob
Response<BlobDownloadInfo>  response = await blob.DownloadAsync();
BlobDownloadInfo downloadInfo = response.Value;
Console.WriteLine((await BinaryData.FromStreamAsync(downloadInfo.Content)).ToString());

Nächste Schritte

In diesem Tutorial haben Sie erfahren, wie Sie .NET-Clientbibliotheken verwenden, um clientseitige Verschlüsselung für Blobupload- und Blobdownloadvorgänge durchzuführen.

Eine umfassende Übersicht über clientseitige Verschlüsselung für Blobs, einschließlich Anweisungen zum Migrieren verschlüsselter Daten zu Version 2, finden Sie unter Clientseitige Verschlüsselung für Blobs.

Weitere Informationen zu Azure Key Vault finden Sie auf der Übersichtsseite für Azure Key Vault.