Konfigurieren des Schutzes von Daten in ASP.NET Core

Wenn das Datenschutzsystem initialisiert wird, werden Standardeinstellungen basierend auf der Betriebsumgebung angewandt. Diese Einstellungen eignen sich für Apps, die auf einem einzelnen Computer ausgeführt werden. Es gibt jedoch Fälle, in denen Entwickler*innen die Standardeinstellungen ändern möchten:

  • Die App ist auf mehrere Computer verteilt.
  • Es gelten Complianceanforderungen.

Für diese Szenarien bietet das Datenschutzsystem eine umfangreiche Konfigurations-API.

Warnung

Ähnlich wie bei Konfigurationsdateien sollte der Schlüsselring für den Datenschutz mit entsprechenden Berechtigungen geschützt werden. Sie können zwar Schlüssel im rest verschlüsseln, aber dies hindert Angreifer*innen nicht daran, neue Schlüssel zu erstellen. Folglich wird die Sicherheit Ihrer App beeinträchtigt. Der mit Datenschutz konfigurierte Speicherort sollte auf die App selbst beschränkt sein, ähnlich wie beim Schutz von Konfigurationsdateien. Wenn Sie sich beispielsweise dafür entscheiden, Ihren Schlüsselring auf dem Datenträger zu speichern, verwenden Sie Dateisystemberechtigungen. Stellen Sie sicher, dass nur die identity, unter der Ihre Web-App ausgeführt wird, über Lese-, Schreib- und Erstellungszugriff auf dieses Verzeichnis verfügt. Wenn Sie Azure Blob Storage verwenden, sollte nur die Web-App die Möglichkeit haben, Einträge im Blobspeicher usw. zu lesen oder zu schreiben oder neue Einträge zu erstellen.

Die Erweiterungsmethode AddDataProtection gibt einen IDataProtectionBuilder zurück. IDataProtectionBuilder macht Erweiterungsmethoden verfügbar, die Sie verketten können, um Datenschutzoptionen zu konfigurieren.

Hinweis

Dieser Artikel wurde für eine App geschrieben, die in einem Docker-Container ausgeführt wird. In einem Docker-Container hat die App immer denselben Pfad und daher denselben Anwendungsdiskriminator. Apps, die in mehreren Umgebungen ausgeführt werden (z. B. lokal und bereitgestellt), müssen den Standard-Anwendungsdiskriminator für die Umgebung festlegen. Das Ausführen einer App in mehreren Umgebungen liegt außerhalb des Umfangs dieses Artikels.

Die folgenden NuGet-Pakete sind für die in diesem Artikel verwendeten Datenschutzerweiterungen erforderlich:

ProtectKeysWithAzureKeyVault

Melden Sie sich mit der Befehlszeilenschnittstelle bei Azure an, z. B.:

az login

Um Schlüssel mit Azure Key Vault zu verwalten, konfigurieren Sie das System mit ProtectKeysWithAzureKeyVault in Program.cs. blobUriWithSasToken ist der vollständige URI, unter dem die Schlüsseldatei gespeichert werden soll. Der URI muss das SAS-Token als Abfragezeichenfolgenparameter enthalten:

builder.Services.AddDataProtection()
    .PersistKeysToAzureBlobStorage(new Uri("<blobUriWithSasToken>"))
    .ProtectKeysWithAzureKeyVault(new Uri("<keyIdentifier>"), new DefaultAzureCredential());

Damit eine App mit Key Vault kommunizieren und sich selbst bei dem Dienst autorisieren kann, muss das Paket Azure.Identity hinzugefügt werden.

Legen Sie den Speicherort des Schlüsselrings fest (z. B PersistKeysToAzureBlobStorage). Der Speicherort muss festgelegt werden, da beim Aufrufen von ProtectKeysWithAzureKeyVault ein IXmlEncryptor implementiert wird, der die automatischen Datenschutzeinstellungen deaktiviert, einschließlich des Speicherorts für den Schlüsselring. Im vorherigen Beispiel wird Azure Blob Storage verwendet, um den Schlüsselring zu speichern. Weitere Informationen finden Sie unter Schlüsselspeicheranbieter: Azure Storage. Sie können den Schlüsselring mit PersistKeysToFileSystem auch lokal speichern.

keyIdentifier ist der Schlüsselbezeichner im Schlüsseltresor, der für die Schlüsselverschlüsselung verwendet wird. Ein Schlüssel, der im Schlüsseltresor dataprotection im contosokeyvault erstellt wurde, hat z. B. den Schlüsselbezeichner https://contosokeyvault.vault.azure.net/keys/dataprotection/. Stellen Sie der App die Berechtigungen Abrufen, Schlüssel entpacken und Schlüssel packen für den Schlüsseltresor bereit.

ProtectKeysWithAzureKeyVault-Überladungen:

Wenn die App die älteren Azure-Pakete (Microsoft.AspNetCore.DataProtection.AzureStorage und Microsoft.AspNetCore.DataProtection.AzureKeyVault) verwendet, wird empfohlen, diese Verweise zu entfernen und auf Azure.Extensions.AspNetCore.DataProtection.Blobs und Azure.Extensions.AspNetCore.DataProtection.Keys zu aktualisieren. In diesen Paketen werden neue Updates bereitgestellt und einige wichtige Sicherheits- und Stabilitätsprobleme mit den älteren Paketen behoben.

builder.Services.AddDataProtection()
    // This blob must already exist before the application is run
    .PersistKeysToAzureBlobStorage("<storageAccountConnectionString", "<containerName>", "<blobName>")
    // Removing this line below for an initial run will ensure the file is created correctly
    .ProtectKeysWithAzureKeyVault(new Uri("<keyIdentifier>"), new DefaultAzureCredential());

PersistKeysToFileSystem

Um Schlüssel auf einer UNC-Freigabe statt am Standardspeicherort %LOCALAPPDATA% zu speichern, konfigurieren Sie das System mit PersistKeysToFileSystem:

builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"));

Warnung

Wenn Sie den Speicherort der Schlüssel ändern, verschlüsselt das System ruhende im rest nicht mehr automatisch, da es nicht weiß, ob DPAPI ein geeigneter Verschlüsselungsmechanismus ist.

PersistKeysToDbContext

Um Schlüssel in einer Datenbank mit EntityFramework zu speichern, konfigurieren Sie das System mit dem Paket Microsoft.AspNetCore.DataProtection.EntityFrameworkCore:

builder.Services.AddDataProtection()
    .PersistKeysToDbContext<SampleDbContext>();

Der vorangehende Code speichert die Schlüssel in der konfigurierten Datenbank. Der verwendete Datenbankkontext muss IDataProtectionKeyContext implementieren. IDataProtectionKeyContext macht die DataProtectionKeys-Eigenschaft verfügbar.

public DbSet<DataProtectionKey> DataProtectionKeys { get; set; } = null!;

Diese Eigenschaft stellt die Tabelle dar, in der die Schlüssel gespeichert werden. Erstellen Sie die Tabelle manuell oder mit DbContext-Migrationen. Weitere Informationen finden Sie unter DataProtectionKey.

ProtectKeysWith*

Sie können das System zum Schutz von Schlüsseln im rest konfigurieren, indem Sie eine derProtectKeysWith*-Konfigurations-APIs aufrufen. Im folgenden Beispiel werden die Schlüssel auf einer UNC-Freigabe gespeichert, und Schlüssel in rest werden mit einem bestimmten X.509-Zertifikat verschlüsselt:

builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
    .ProtectKeysWithCertificate(builder.Configuration["CertificateThumbprint"]);

Sie können für ProtectKeysWithCertificate ein X509Certificate2 angeben, z. B. ein Zertifikat, das aus einer Datei geladen wurde:

builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
    .ProtectKeysWithCertificate(
        new X509Certificate2("certificate.pfx", builder.Configuration["CertificatePassword"]));

Weitere Beispiele und Erläuterungen zu den integrierten Schlüsselverschlüsselungsmechanismen finden Sie unter Verschlüsselung von Schlüsseln im Rest.

UnprotectKeysWithAnyCertificate

Sie können Zertifikate rotieren und Schlüssel im rest entschlüsseln, indem Sie ein Array von X509Certificate2-Zertifikaten mit UnprotectKeysWithAnyCertificate verwenden:

builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
    .ProtectKeysWithCertificate(
        new X509Certificate2("certificate.pfx", builder.Configuration["CertificatePassword"]))
    .UnprotectKeysWithAnyCertificate(
        new X509Certificate2("certificate_1.pfx", builder.Configuration["CertificatePassword_1"]),
        new X509Certificate2("certificate_2.pfx", builder.Configuration["CertificatePassword_2"]));

SetDefaultKeyLifetime

Verwenden Sie SetDefaultKeyLifetime, um das System für die Verwendung einer Schlüssellebensdauer von 14 Tagen anstelle der Standarddauer von 90 Tagen zu konfigurieren:

builder.Services.AddDataProtection()
    .SetDefaultKeyLifetime(TimeSpan.FromDays(14));

SetApplicationName

Standardmäßig isoliert das Datenschutzsystem Apps basierend auf ihren Inhaltsstammpfaden voneinander, auch wenn sie dasselbe physische Schlüsselrepository verwenden. Diese Isolation verhindert, dass die Apps die geschützten Nutzdaten anderer Apps verstehen.

So nutzen Sie geschützte Nutzdaten gemeinsam für Apps

  • Konfigurieren Sie SetApplicationName in jeder App mit demselben Wert.
  • Verwenden Sie für alle Apps dieselbe Version des Datenschutz-API-Stapels. Führen Sie eine der folgenden Aktionen in den Projektdateien der Apps aus:
builder.Services.AddDataProtection()
    .SetApplicationName("<sharedApplicationName>");

SetApplicationName legt den DataProtectionOptions.ApplicationDiscriminator intern fest. Zu Problembehandlungszwecken kann der Wert, der dem Diskriminator vom Framework zugewiesen wurde, mit dem folgenden Code protokolliert werden, der in Program.cs nach der integrierten WebApplication platziert wird:

var discriminator = app.Services.GetRequiredService<IOptions<DataProtectionOptions>>()
    .Value.ApplicationDiscriminator;
app.Logger.LogInformation("ApplicationDiscriminator: {ApplicationDiscriminator}", discriminator);

Weitere Informationen zur Verwendung des Diskriminators finden Sie in den folgenden Abschnitten weiter unten in diesem Artikel:

Warnung

In .NET 6 normalisiert WebApplicationBuilder den Inhaltsstammpfad so, dass er mit DirectorySeparatorChar endet. Unter Windows endet der Inhaltsstammpfad beispielsweise auf \ und unter Linux auf /. Andere Hosts normalisieren den Pfad nicht. Die meisten Apps, die von HostBuilder oder WebHostBuilder migriert werden, haben nicht denselben App-Namen, da sie nicht auf DirectorySeparatorChar enden. Um dieses Problem zu umgehen, entfernen Sie das Verzeichnistrennzeichen und legen den App-Namen manuell fest, wie im folgenden Code gezeigt:

using Microsoft.AspNetCore.DataProtection;
using System.Reflection;

var builder = WebApplication.CreateBuilder(args);
var trimmedContentRootPath = builder.Environment.ContentRootPath.TrimEnd(Path.DirectorySeparatorChar);
builder.Services.AddDataProtection()
 .SetApplicationName(trimmedContentRootPath);
var app = builder.Build();

app.MapGet("/", () => Assembly.GetEntryAssembly()!.GetName().Name);

app.Run();

DisableAutomaticKeyGeneration

Möglicherweise möchten Sie in Ihrem Szenario nicht, dass eine App Schlüssel automatisch rotiert (neue Schlüssel erstellt), wenn diese demnächst ablaufen. Ein Beispiel für dieses Szenario sind Apps, die in einer hierarchischen Beziehung (primär/sekundär) eingerichtet wurden, bei der nur die primäre App für Schlüsselverwaltungsaspekte verantwortlich ist und sekundäre Apps lediglich über eine schreibgeschützte Ansicht des Schlüsselrings verfügen. Die sekundären Apps können so konfiguriert werden, dass der Schlüsselring als schreibgeschützt behandelt wird, indem das System mit DisableAutomaticKeyGeneration konfiguriert wird:

builder.Services.AddDataProtection()
    .DisableAutomaticKeyGeneration();

Anwendungsisolation

Wenn das Datenschutzsystem von einem ASP.NET Core-Host bereitgestellt wird, isoliert es Apps automatisch voneinander, auch wenn diese Apps unter demselben Workerprozesskonto ausgeführt werden und dasselbe Hauptschlüsselmaterial verwenden. Dies ähnelt dem IsolateApps-Modifizierer aus dem <machineKey>-Element von „System.Web“.

Der Isolationsmechanismus betrachtet jede App auf dem lokalen Computer als eindeutigen Mandanten, sodass der IDataProtector als Stamm für jede App automatisch die App-ID als Diskriminator enthält (ApplicationDiscriminator). Die eindeutige ID der App ist ihr physischer Pfad:

  • Bei in IIS gehosteten Apps ist die eindeutige ID der physische IIS-Pfad der App. Wenn eine App in einer Webfarmumgebung bereitgestellt wird, ist dieser Wert unveränderlich, sofern die IIS-Umgebungen auf allen Computern in der Webfarm gleich konfiguriert sind.
  • Bei selbstgehosteten Apps, die auf dem Kestrel-Server ausgeführt werden, ist die eindeutige ID der physische Pfad zur App auf dem Datenträger.

Der eindeutige Bezeichner ist so konzipiert, dass er beim Zurücksetzen beibehalten wird – sowohl für die einzelne App als auch für den Computer selbst.

Bei diesem Isolationsmechanismus wird davon ausgegangen, dass die Apps nicht böswillig sind. Eine böswillige App kann sich immer auf jede andere App auswirken, die unter demselben Workerprozesskonto ausgeführt wird. In einer gemeinsam genutzten Hostingumgebung, in der Apps gegenseitig nicht vertrauenswürdig sind, sollte der Hostinganbieter Maßnahmen ergreifen, um die Isolation zwischen Apps auf Betriebssystemebene sicherzustellen. Dies schließt auch die Trennung der zugrunde liegenden Schlüsselrepositorys der Apps ein.

Wenn das Datenschutzsystem nicht von einem ASP.NET Core-Host bereitgestellt wird (z. B. wenn Sie ihn über den konkreten Typ DataProtectionProvider instanziieren), ist die App-Isolation standardmäßig deaktiviert. Wenn die App-Isolation deaktiviert ist, können alle Apps, die dasselbe Schlüsselmaterial verwenden, Nutzdaten gemeinsam nutzen, solange sie die entsprechenden Zwecke bereitstellen. Um in einer solchen Umgebung App-Isolation bereitzustellen, rufen Sie die SetApplicationName-Methode für das Konfigurationsobjekt auf und geben einen eindeutigen Namen für jede App an.

Datenschutz und App-Isolation

Berücksichtigen Sie die folgenden Punkte bei der App-Isolation:

  • Wenn mehrere Apps auf dasselbe Schlüsselrepository verweisen, wird beabsichtigt, dass die Apps dasselbe Hauptschlüsselmaterial gemeinsam nutzen. Datenschutz wird unter der Annahme entwickelt, dass alle Apps, die einen Schlüsselring teilen, auf alle Elemente in diesem Schlüsselring zugreifen können. Der eindeutige Bezeichner der Anwendung wird verwendet, um anwendungsspezifische Schlüssel zu isolieren, die von den bereitgestellten Schlüsseln des Schlüsselrings abgeleitet werden. Es wird nicht erwartet, dass Berechtigungen auf Elementebene, wie sie z. B. von Azure KeyVault bereitgestellt werden, verwendet werden, um eine zusätzliche Isolation zu erzwingen. Beim Versuch, Berechtigungen auf Elementebene zu verwenden, werden Anwendungsfehler generiert. Wenn Sie sich nicht auf die integrierte Anwendungsisolation verlassen möchten, sollten Sie separate Schlüsselspeicherorte verwenden, die nicht von Anwendungen gemeinsam genutzt werden.

  • Der Anwendungsdiskriminator (ApplicationDiscriminator) wird verwendet, um verschiedenen Apps zu ermöglichen, dasselbe Hauptschlüsselmaterial gemeinsam zu nutzen, ihre kryptografischen Nutzdaten jedoch voneinander getrennt zu halten. Damit die Apps die kryptografischen Nutzdaten der jeweils anderen lesen können, müssen sie über denselben Anwendungsdiskriminator verfügen, der durch Aufrufen von SetApplicationName festgelegt werden kann.

  • Wenn eine App kompromittiert wurde (z. B. durch einen RCE-Angriff), muss das gesamte Hauptschlüsselmaterial, auf das diese App zugreifen kann, ebenfalls als kompromittiert angesehen werden, unabhängig vom Schutzstatus im Ruhezustand. Dies bedeutet auch, dass, wenn zwei Apps auf dasselbe Repository zeigen, eine Kompromittierung von einer funktional einer Kompromittierung von beiden entspricht, selbst wenn sie unterschiedliche App-Diskriminatoren verwenden.

    Diese Klausel der „funktionell gleichwertigen Kompromittierung beider Apps“ gilt auch dann, wenn die beiden Apps unterschiedliche Mechanismen für den Schlüsselschutz im rest verwenden. Dies ist in der Regel keine zu erwartende Konfiguration. Der Mechanismus zum Schutz von Daten im rest soll Schutz bieten, falls Cyber-Angreifer*innen Lesezugriff auf das Repository erlangen. Cyber-Angreifende, die Schreibzugriff auf das Repository erlangen (z. B. indem sie die Codeausführungsberechtigung innerhalb einer App erhalten haben), können bösartige Schlüssel in den Speicher einfügen. Das Datenschutzsystem bietet absichtlich keinen Schutz vor Cyber-Angreifer*innen, die Schreibzugriff auf das Schlüsselrepository erlangen.

  • Wenn Apps wirklich isoliert voneinander bleiben müssen, sollten sie unterschiedliche Schlüsselrepositorys verwenden. Dies liegt natürlich außerhalb der Definition von „isoliert“. Apps sind nicht isoliert, wenn sie alle über Lese- und Schreibzugriff auf die Datenspeicher der anderen verfügen.

Ändern von Algorithmen mit UseCryptographicAlgorithms

Mit dem Datenschutzstapel können Sie den Standardalgorithmus ändern, der von neu generierten Schlüsseln verwendet wird. Die einfachste Möglichkeit besteht darin, im Konfigurationsrückruf UseCryptographicAlgorithms aufzurufen:

builder.Services.AddDataProtection()
    .UseCryptographicAlgorithms(new AuthenticatedEncryptorConfiguration
    {
        EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
        ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
    });

Der Standardverschlüsselungsalgorithmus ist AES-256-CBC, und der Standardüberprüfungsalgorithmus ist HMACSHA256. Die Standardrichtlinie kann von Systemadministrator*innen über eine computerweite Richtlinie festgelegt werden, aber ein expliziter Aufruf von UseCryptographicAlgorithms setzt die Standardrichtlinie außer Kraft.

Durch Aufrufen von UseCryptographicAlgorithms können Sie den gewünschten Algorithmus aus einer vordefinierten Liste integrierter Algorithmen angeben. Um die Implementierungsdetails des Algorithmus müssen Sie sich nicht kümmern. Im obigen Szenario versucht das Datenschutzsystem, bei einer Ausführung unter Windows die CNG-Implementierung von AES zu verwenden. Andernfalls greift es auf die verwaltete System.Security.Cryptography.Aes-Klasse zurück.

Sie können eine Implementierung manuell über einen Aufruf von UseCustomCryptographicAlgorithms angeben.

Tipp

Das Ändern von Algorithmen wirkt sich nicht auf vorhandene Schlüssel im Schlüsselring aus. Dies wirkt sich nur auf neu generierte Schlüssel aus.

Angeben von benutzerdefinierten verwalteten Algorithmen

Um benutzerdefinierte verwaltete Algorithmen anzugeben, erstellen Sie eine Instanz von ManagedAuthenticatedEncryptorConfiguration, die auf die Implementierungstypen verweist:

builder.Services.AddDataProtection()
    .UseCustomCryptographicAlgorithms(new ManagedAuthenticatedEncryptorConfiguration
    {
        // A type that subclasses SymmetricAlgorithm
        EncryptionAlgorithmType = typeof(Aes),

        // Specified in bits
        EncryptionAlgorithmKeySize = 256,

        // A type that subclasses KeyedHashAlgorithm
        ValidationAlgorithmType = typeof(HMACSHA256)
    });

Im Allgemeinen müssen die *Type-Eigenschaften auf konkrete, instanziierbare (über einen öffentlichen parameterlosen ctor) Implementierungen von SymmetricAlgorithm und KeyedHashAlgorithm verweisen, wobei die Sonderfälle im System einige Werte wie z. B typeof(Aes) zur Vereinfachung aufweisen.

Hinweis

Ein SymmetricAlgorithm muss eine Schlüssellänge von ≥ 128 Bit und eine Blockgröße von ≥ 64 Bit aufweisen und die Verschlüsselung im CBC-Modus mit PKCS #7-Auffüllung unterstützen. Der KeyedHashAlgorithm muss eine Hashgröße von >= 128 Bit aufweisen und Schlüssel mit einer Länge unterstützen, die der Hashlänge des Hashalgorithmus entspricht. KeyedHashAlgorithm muss nicht unbedingt HMAC sein.

Angeben benutzerdefinierter Windows-CNG-Algorithmen

Um einen benutzerdefinierten Windows-CNG-Algorithmus mithilfe der Verschlüsselung im CBC-Modus mit HMAC-Validierung anzugeben, erstellen Sie eine Instanz von CngCbcAuthenticatedEncryptorConfiguration, die die Algorithmusinformationen enthält:

builder.Services.AddDataProtection()
    .UseCustomCryptographicAlgorithms(new CngCbcAuthenticatedEncryptorConfiguration
    {
        // Passed to BCryptOpenAlgorithmProvider
        EncryptionAlgorithm = "AES",
        EncryptionAlgorithmProvider = null,

        // Specified in bits
        EncryptionAlgorithmKeySize = 256,

        // Passed to BCryptOpenAlgorithmProvider
        HashAlgorithm = "SHA256",
        HashAlgorithmProvider = null
    });

Hinweis

Der symmetrische Blockchiffre-Algorithmus muss eine Schlüssellänge von >= 128 Bit und eine Blockgröße von >= 64 Bit aufweisen und die Verschlüsselung im CBC-Modus mit PKCS #7-Auffüllung unterstützen. Der Hashalgorithmus muss eine Hashgröße von >= 128 Bit aufweisen und das Öffnen mit dem Flag BCRYPT_ALG_HANDLE_HMAC_FLAG unterstützen. Die *Provider-Eigenschaften können auf NULL festgelegt werden, um den Standardanbieter für den angegebenen Algorithmus zu verwenden. Weitere Informationen finden Sie in der Dokumentation zu BCryptOpenAlgorithmProvider.

Um einen benutzerdefinierten Windows-CNG-Algorithmus mithilfe der Verschlüsselung im Galois/Counter-Modus mit Validierung anzugeben, erstellen Sie eine Instanz von CngGcmAuthenticatedEncryptorConfiguration, die die Algorithmusinformationen enthält:

builder.Services.AddDataProtection()
    .UseCustomCryptographicAlgorithms(new CngGcmAuthenticatedEncryptorConfiguration
    {
        // Passed to BCryptOpenAlgorithmProvider
        EncryptionAlgorithm = "AES",
        EncryptionAlgorithmProvider = null,

        // Specified in bits
        EncryptionAlgorithmKeySize = 256
    });

Hinweis

Der symmetrische Blockchiffre-Algorithmus muss eine Schlüssellänge von >= 128 Bit und eine Blockgröße von genau 128 Bit aufweisen und die GCM-Verschlüsselung unterstützen. Sie können die EncryptionAlgorithmProvider-Eigenschaft auf NULL festlegen, um den Standardanbieter für den angegebenen Algorithmus zu verwenden. Weitere Informationen finden Sie in der Dokumentation zu BCryptOpenAlgorithmProvider.

Angeben anderer benutzerdefinierter Algorithmen

Obwohl das Datenschutzsystem nicht als besondere API verfügbar gemacht wird, ist es erweiterbar genug, um die Angabe fast jeden Algorithmustyps zu ermöglichen. Es ist beispielsweise möglich, alle Schlüssel, die in einem Hardwaresicherheitsmodul (HSM) enthalten sind, beizubehalten und eine benutzerdefinierte Implementierung der wichtigsten Ver- und Entschlüsselungsroutinen bereitzustellen. Weitere Informationen finden Sie unter IAuthenticatedEncryptor in Kryptografieerweiterbarkeit in Core.

Beibehalten von Schlüsseln beim Hosten in einem Docker-Container

Beim Hosten in einem Docker-Container sollten Schlüssel mit einer der folgenden Optionen verwaltet werden:

  • In einem Ordner, der ein Docker-Volume ist, das über die Lebensdauer des Containers hinaus beibehalten wird, z. B. ein freigegebenes Volume oder ein vom Host bereitgestelltes Volume
  • Bei einem externen Anbieter, z. B. Azure Blob Storage (siehe Abschnitt ProtectKeysWithAzureKeyVault) oder Redis

Beibehalten von Schlüsseln mit Redis

Zum Speichern von Schlüsseln sollten nur Redis-Versionen verwendet werden, die Redis Data Persistence unterstützen. Azure Blob Storage ist persistent und kann zum Speichern von Schlüsseln verwendet werden. Weitere Informationen finden Sie in diesem GitHub-Issue.

Protokollieren des Datenschutzes

Aktivieren Sie die Protokollierung auf Information-Ebene von DataProtection, um die Diagnose von Problemen zu unterstützen. Die folgende Datei appsettings.json ermöglicht die Protokollierung auf Informationsebene der Datenschutz-API:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.AspNetCore.DataProtection": "Information"
    }
  },
  "AllowedHosts": "*"
}

Weitere Informationen zur Protokollierung finden Sie unter Protokollieren in .NET Core und ASP.NET Core.

Zusätzliche Ressourcen

Wenn das Datenschutzsystem initialisiert wird, werden Standardeinstellungen basierend auf der Betriebsumgebung angewandt. Diese Einstellungen eignen sich für Apps, die auf einem einzelnen Computer ausgeführt werden. Es gibt jedoch Fälle, in denen Entwickler*innen die Standardeinstellungen ändern möchten:

  • Die App ist auf mehrere Computer verteilt.
  • Es gelten Complianceanforderungen.

Für diese Szenarien bietet das Datenschutzsystem eine umfangreiche Konfigurations-API.

Warnung

Ähnlich wie bei Konfigurationsdateien sollte der Schlüsselring für den Datenschutz mit entsprechenden Berechtigungen geschützt werden. Sie können zwar Schlüssel im rest verschlüsseln, aber dies hindert Angreifer*innen nicht daran, neue Schlüssel zu erstellen. Folglich wird die Sicherheit Ihrer App beeinträchtigt. Der mit Datenschutz konfigurierte Speicherort sollte auf die App selbst beschränkt sein, ähnlich wie beim Schutz von Konfigurationsdateien. Wenn Sie sich beispielsweise dafür entscheiden, Ihren Schlüsselring auf dem Datenträger zu speichern, verwenden Sie Dateisystemberechtigungen. Stellen Sie sicher, dass nur die identity, unter der Ihre Web-App ausgeführt wird, über Lese-, Schreib- und Erstellungszugriff auf dieses Verzeichnis verfügt. Wenn Sie Azure Blob Storage verwenden, sollte nur die Web-App die Möglichkeit haben, Einträge im Blobspeicher usw. zu lesen oder zu schreiben oder neue Einträge zu erstellen.

Die Erweiterungsmethode AddDataProtection gibt einen IDataProtectionBuilder zurück. IDataProtectionBuilder macht Erweiterungsmethoden verfügbar, die Sie verketten können, um Datenschutzoptionen zu konfigurieren.

Die folgenden NuGet-Pakete sind für die in diesem Artikel verwendeten Datenschutzerweiterungen erforderlich:

ProtectKeysWithAzureKeyVault

Melden Sie sich mit der Befehlszeilenschnittstelle bei Azure an, z. B.:

az login

Um Schlüssel in Azure Key Vault zu speichern, konfigurieren Sie das System mit ProtectKeysWithAzureKeyVault in der Startup-Klasse. blobUriWithSasToken ist der vollständige URI, unter dem die Schlüsseldatei gespeichert werden soll. Der URI muss das SAS-Token als Abfragezeichenfolgenparameter enthalten:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToAzureBlobStorage(new Uri("<blobUriWithSasToken>"))
        .ProtectKeysWithAzureKeyVault(new Uri("<keyIdentifier>"), new DefaultAzureCredential());
}

Damit eine App mit Key Vault kommunizieren und sich selbst bei dem Dienst autorisieren kann, muss das Paket Azure.Identity hinzugefügt werden.

Legen Sie den Speicherort des Schlüsselrings fest (z. B PersistKeysToAzureBlobStorage). Der Speicherort muss festgelegt werden, da beim Aufrufen von ProtectKeysWithAzureKeyVault ein IXmlEncryptor implementiert wird, der die automatischen Datenschutzeinstellungen deaktiviert, einschließlich des Speicherorts für den Schlüsselring. Im vorherigen Beispiel wird Azure Blob Storage verwendet, um den Schlüsselring zu speichern. Weitere Informationen finden Sie unter Schlüsselspeicheranbieter: Azure Storage. Sie können den Schlüsselring mit PersistKeysToFileSystem auch lokal speichern.

keyIdentifier ist der Schlüsselbezeichner im Schlüsseltresor, der für die Schlüsselverschlüsselung verwendet wird. Ein Schlüssel, der im Schlüsseltresor dataprotection im contosokeyvault erstellt wurde, hat z. B. den Schlüsselbezeichner https://contosokeyvault.vault.azure.net/keys/dataprotection/. Stellen Sie der App die Berechtigungen Abrufen, Schlüssel entpacken und Schlüssel packen für den Schlüsseltresor bereit.

ProtectKeysWithAzureKeyVault-Überladungen:

Wenn die App die älteren Azure-Pakete (Microsoft.AspNetCore.DataProtection.AzureStorage und Microsoft.AspNetCore.DataProtection.AzureKeyVault) verwendet, wird empfohlen, diese Verweise zu entfernen und auf Azure.Extensions.AspNetCore.DataProtection.Blobs und Azure.Extensions.AspNetCore.DataProtection.Keys zu aktualisieren. In diesen Paketen werden neue Updates bereitgestellt und einige wichtige Sicherheits- und Stabilitätsprobleme mit den älteren Paketen behoben.

services.AddDataProtection()
    //This blob must already exist before the application is run
    .PersistKeysToAzureBlobStorage("<storage account connection string", "<key store container name>", "<key store blob name>")
    //Removing this line below for an initial run will ensure the file is created correctly
    .ProtectKeysWithAzureKeyVault(new Uri("<keyIdentifier>"), new DefaultAzureCredential());

Warnung

In diesem Artikel wird die Verwendung von Verbindungszeichenfolge gezeigt. Bei einer lokalen Datenbank muss der Benutzer nicht authentifiziert werden, aber in der Produktion enthalten Verbindungszeichenfolge manchmal ein Kennwort für die Authentifizierung. Ein Ressourcenbesitzer-Kennwortanmeldeinformation (ROPC) ist ein Sicherheitsrisiko, das in Produktionsdatenbanken vermieden werden sollte. Produktions-Apps sollten den sichersten verfügbaren Ablauf für die Authentifizierung verwenden. Weitere Informationen zur Authentifizierung für Apps, die für Test- oder Produktionsumgebungen bereitgestellt werden, finden Sie unter Sichere Authentifizierungsflüsse.

PersistKeysToFileSystem

Um Schlüssel auf einer UNC-Freigabe statt am Standardspeicherort %LOCALAPPDATA% zu speichern, konfigurieren Sie das System mit PersistKeysToFileSystem:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"));
}

Warnung

Wenn Sie den Speicherort der Schlüssel ändern, verschlüsselt das System ruhende im rest nicht mehr automatisch, da es nicht weiß, ob DPAPI ein geeigneter Verschlüsselungsmechanismus ist.

PersistKeysToDbContext

Um Schlüssel in einer Datenbank mit EntityFramework zu speichern, konfigurieren Sie das System mit dem Paket Microsoft.AspNetCore.DataProtection.EntityFrameworkCore:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToDbContext<DbContext>()
}

Der vorangehende Code speichert die Schlüssel in der konfigurierten Datenbank. Der verwendete Datenbankkontext muss IDataProtectionKeyContext implementieren. IDataProtectionKeyContext macht die DataProtectionKeys-Eigenschaft verfügbar.

public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }

Diese Eigenschaft stellt die Tabelle dar, in der die Schlüssel gespeichert werden. Erstellen Sie die Tabelle manuell oder mit DbContext-Migrationen. Weitere Informationen finden Sie unter DataProtectionKey.

ProtectKeysWith*

Sie können das System zum Schutz von Schlüsseln im rest konfigurieren, indem Sie eine derProtectKeysWith*-Konfigurations-APIs aufrufen. Im folgenden Beispiel werden die Schlüssel auf einer UNC-Freigabe gespeichert, und Schlüssel in rest werden mit einem bestimmten X.509-Zertifikat verschlüsselt:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
        .ProtectKeysWithCertificate(Configuration["Thumbprint"]);
}

Sie können für ProtectKeysWithCertificate ein X509Certificate2 angeben, z. B. ein Zertifikat, das aus einer Datei geladen wurde:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
        .ProtectKeysWithCertificate(
            new X509Certificate2("certificate.pfx", Configuration["Thumbprint"]));
}

Weitere Beispiele und Erläuterungen zu den integrierten Schlüsselverschlüsselungsmechanismen finden Sie unter Verschlüsselung von Schlüsseln im Rest.

UnprotectKeysWithAnyCertificate

Sie können Zertifikate rotieren und Schlüssel im rest entschlüsseln, indem Sie ein Array von X509Certificate2-Zertifikaten mit UnprotectKeysWithAnyCertificate verwenden:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
        .ProtectKeysWithCertificate(
            new X509Certificate2("certificate.pfx", Configuration["MyPasswordKey"));
        .UnprotectKeysWithAnyCertificate(
            new X509Certificate2("certificate_old_1.pfx", Configuration["MyPasswordKey_1"]),
            new X509Certificate2("certificate_old_2.pfx", Configuration["MyPasswordKey_2"]));
}

SetDefaultKeyLifetime

Verwenden Sie SetDefaultKeyLifetime, um das System für die Verwendung einer Schlüssellebensdauer von 14 Tagen anstelle der Standarddauer von 90 Tagen zu konfigurieren:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .SetDefaultKeyLifetime(TimeSpan.FromDays(14));
}

SetApplicationName

Standardmäßig isoliert das Datenschutzsystem Apps basierend auf ihren Inhaltsstammpfaden voneinander, auch wenn sie dasselbe physische Schlüsselrepository verwenden. Diese Isolation verhindert, dass die Apps die geschützten Nutzdaten anderer Apps verstehen.

So nutzen Sie geschützte Nutzdaten gemeinsam für Apps

  • Konfigurieren Sie SetApplicationName in jeder App mit demselben Wert.
  • Verwenden Sie für alle Apps dieselbe Version des Datenschutz-API-Stapels. Führen Sie eine der folgenden Aktionen in den Projektdateien der Apps aus:
public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .SetApplicationName("shared app name");
}

SetApplicationName legt den DataProtectionOptions.ApplicationDiscriminator intern fest. Weitere Informationen zur Verwendung des Diskriminators finden Sie in den folgenden Abschnitten weiter unten in diesem Artikel:

DisableAutomaticKeyGeneration

Möglicherweise möchten Sie in Ihrem Szenario nicht, dass eine App Schlüssel automatisch rotiert (neue Schlüssel erstellt), wenn diese demnächst ablaufen. Ein Beispiel für dieses Szenario sind Apps, die in einer hierarchischen Beziehung (primär/sekundär) eingerichtet wurden, bei der nur die primäre App für Schlüsselverwaltungsaspekte verantwortlich ist und sekundäre Apps lediglich über eine schreibgeschützte Ansicht des Schlüsselrings verfügen. Die sekundären Apps können so konfiguriert werden, dass der Schlüsselring als schreibgeschützt behandelt wird, indem das System mit DisableAutomaticKeyGeneration konfiguriert wird:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .DisableAutomaticKeyGeneration();
}

Anwendungsisolation

Wenn das Datenschutzsystem von einem ASP.NET Core-Host bereitgestellt wird, isoliert es Apps automatisch voneinander, auch wenn diese Apps unter demselben Workerprozesskonto ausgeführt werden und dasselbe Hauptschlüsselmaterial verwenden. Dies ähnelt dem IsolateApps-Modifizierer aus dem <machineKey>-Element von „System.Web“.

Der Isolationsmechanismus betrachtet jede App auf dem lokalen Computer als eindeutigen Mandanten, sodass der IDataProtector als Stamm für jede App automatisch die App-ID als Diskriminator enthält (ApplicationDiscriminator). Die eindeutige ID der App ist ihr physischer Pfad:

  • Bei in IIS gehosteten Apps ist die eindeutige ID der physische IIS-Pfad der App. Wenn eine App in einer Webfarmumgebung bereitgestellt wird, ist dieser Wert unveränderlich, sofern die IIS-Umgebungen auf allen Computern in der Webfarm gleich konfiguriert sind.
  • Bei selbstgehosteten Apps, die auf dem Kestrel-Server ausgeführt werden, ist die eindeutige ID der physische Pfad zur App auf dem Datenträger.

Der eindeutige Bezeichner ist so konzipiert, dass er beim Zurücksetzen beibehalten wird – sowohl für die einzelne App als auch für den Computer selbst.

Bei diesem Isolationsmechanismus wird davon ausgegangen, dass die Apps nicht böswillig sind. Eine böswillige App kann sich immer auf jede andere App auswirken, die unter demselben Workerprozesskonto ausgeführt wird. In einer gemeinsam genutzten Hostingumgebung, in der Apps gegenseitig nicht vertrauenswürdig sind, sollte der Hostinganbieter Maßnahmen ergreifen, um die Isolation zwischen Apps auf Betriebssystemebene sicherzustellen. Dies schließt auch die Trennung der zugrunde liegenden Schlüsselrepositorys der Apps ein.

Wenn das Datenschutzsystem nicht von einem ASP.NET Core-Host bereitgestellt wird (z. B. wenn Sie ihn über den konkreten Typ DataProtectionProvider instanziieren), ist die App-Isolation standardmäßig deaktiviert. Wenn die App-Isolation deaktiviert ist, können alle Apps, die dasselbe Schlüsselmaterial verwenden, Nutzdaten gemeinsam nutzen, solange sie die entsprechenden Zwecke bereitstellen. Um in einer solchen Umgebung App-Isolation bereitzustellen, rufen Sie die SetApplicationName-Methode für das Konfigurationsobjekt auf und geben einen eindeutigen Namen für jede App an.

Datenschutz und App-Isolation

Berücksichtigen Sie die folgenden Punkte bei der App-Isolation:

  • Wenn mehrere Apps auf dasselbe Schlüsselrepository verweisen, wird beabsichtigt, dass die Apps dasselbe Hauptschlüsselmaterial gemeinsam nutzen. Datenschutz wird unter der Annahme entwickelt, dass alle Apps, die einen Schlüsselring teilen, auf alle Elemente in diesem Schlüsselring zugreifen können. Der eindeutige Bezeichner der Anwendung wird verwendet, um anwendungsspezifische Schlüssel zu isolieren, die von den bereitgestellten Schlüsseln des Schlüsselrings abgeleitet werden. Es wird nicht erwartet, dass Berechtigungen auf Elementebene, wie sie z. B. von Azure KeyVault bereitgestellt werden, verwendet werden, um eine zusätzliche Isolation zu erzwingen. Beim Versuch, Berechtigungen auf Elementebene zu verwenden, werden Anwendungsfehler generiert. Wenn Sie sich nicht auf die integrierte Anwendungsisolation verlassen möchten, sollten Sie separate Schlüsselspeicherorte verwenden, die nicht von Anwendungen gemeinsam genutzt werden.

  • Der Anwendungsdiskriminator (ApplicationDiscriminator) wird verwendet, um verschiedenen Apps zu ermöglichen, dasselbe Hauptschlüsselmaterial gemeinsam zu nutzen, ihre kryptografischen Nutzdaten jedoch voneinander getrennt zu halten. Damit die Apps die kryptografischen Nutzdaten der jeweils anderen lesen können, müssen sie über denselben Anwendungsdiskriminator verfügen, der durch Aufrufen von SetApplicationName festgelegt werden kann.

  • Wenn eine App kompromittiert wurde (z. B. durch einen RCE-Angriff), muss das gesamte Hauptschlüsselmaterial, auf das diese App zugreifen kann, ebenfalls als kompromittiert angesehen werden, unabhängig vom Schutzstatus im Ruhezustand. Dies bedeutet auch, dass, wenn zwei Apps auf dasselbe Repository zeigen, eine Kompromittierung von einer funktional einer Kompromittierung von beiden entspricht, selbst wenn sie unterschiedliche App-Diskriminatoren verwenden.

    Diese Klausel der „funktionell gleichwertigen Kompromittierung beider Apps“ gilt auch dann, wenn die beiden Apps unterschiedliche Mechanismen für den Schlüsselschutz im rest verwenden. Dies ist in der Regel keine zu erwartende Konfiguration. Der Mechanismus zum Schutz von Daten im rest soll Schutz bieten, falls Cyber-Angreifer*innen Lesezugriff auf das Repository erlangen. Cyber-Angreifende, die Schreibzugriff auf das Repository erlangen (z. B. indem sie die Codeausführungsberechtigung innerhalb einer App erhalten haben), können bösartige Schlüssel in den Speicher einfügen. Das Datenschutzsystem bietet absichtlich keinen Schutz vor Cyber-Angreifer*innen, die Schreibzugriff auf das Schlüsselrepository erlangen.

  • Wenn Apps wirklich isoliert voneinander bleiben müssen, sollten sie unterschiedliche Schlüsselrepositorys verwenden. Dies liegt natürlich außerhalb der Definition von „isoliert“. Apps sind nicht isoliert, wenn sie alle über Lese- und Schreibzugriff auf die Datenspeicher der anderen verfügen.

Ändern von Algorithmen mit UseCryptographicAlgorithms

Mit dem Datenschutzstapel können Sie den Standardalgorithmus ändern, der von neu generierten Schlüsseln verwendet wird. Die einfachste Möglichkeit besteht darin, im Konfigurationsrückruf UseCryptographicAlgorithms aufzurufen:

services.AddDataProtection()
    .UseCryptographicAlgorithms(
        new AuthenticatedEncryptorConfiguration()
    {
        EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
        ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
    });

Der Standardverschlüsselungsalgorithmus ist AES-256-CBC, und der Standardüberprüfungsalgorithmus ist HMACSHA256. Die Standardrichtlinie kann von Systemadministrator*innen über eine computerweite Richtlinie festgelegt werden, aber ein expliziter Aufruf von UseCryptographicAlgorithms setzt die Standardrichtlinie außer Kraft.

Durch Aufrufen von UseCryptographicAlgorithms können Sie den gewünschten Algorithmus aus einer vordefinierten Liste integrierter Algorithmen angeben. Um die Implementierungsdetails des Algorithmus müssen Sie sich nicht kümmern. Im obigen Szenario versucht das Datenschutzsystem, bei einer Ausführung unter Windows die CNG-Implementierung von AES zu verwenden. Andernfalls greift es auf die verwaltete System.Security.Cryptography.Aes-Klasse zurück.

Sie können eine Implementierung manuell über einen Aufruf von UseCustomCryptographicAlgorithms angeben.

Tipp

Das Ändern von Algorithmen wirkt sich nicht auf vorhandene Schlüssel im Schlüsselring aus. Dies wirkt sich nur auf neu generierte Schlüssel aus.

Angeben von benutzerdefinierten verwalteten Algorithmen

Um benutzerdefinierte verwaltete Algorithmen anzugeben, erstellen Sie eine Instanz von ManagedAuthenticatedEncryptorConfiguration, die auf die Implementierungstypen verweist:

serviceCollection.AddDataProtection()
    .UseCustomCryptographicAlgorithms(
        new ManagedAuthenticatedEncryptorConfiguration()
    {
        // A type that subclasses SymmetricAlgorithm
        EncryptionAlgorithmType = typeof(Aes),

        // Specified in bits
        EncryptionAlgorithmKeySize = 256,

        // A type that subclasses KeyedHashAlgorithm
        ValidationAlgorithmType = typeof(HMACSHA256)
    });

Im Allgemeinen müssen die *Type-Eigenschaften auf konkrete, instanziierbare (über einen öffentlichen parameterlosen ctor) Implementierungen von SymmetricAlgorithm und KeyedHashAlgorithm verweisen, wobei die Sonderfälle im System einige Werte wie z. B typeof(Aes) zur Vereinfachung aufweisen.

Hinweis

Ein SymmetricAlgorithm muss eine Schlüssellänge von ≥ 128 Bit und eine Blockgröße von ≥ 64 Bit aufweisen und die Verschlüsselung im CBC-Modus mit PKCS #7-Auffüllung unterstützen. Der KeyedHashAlgorithm muss eine Hashgröße von >= 128 Bit aufweisen und Schlüssel mit einer Länge unterstützen, die der Hashlänge des Hashalgorithmus entspricht. KeyedHashAlgorithm muss nicht unbedingt HMAC sein.

Angeben benutzerdefinierter Windows-CNG-Algorithmen

Um einen benutzerdefinierten Windows-CNG-Algorithmus mithilfe der Verschlüsselung im CBC-Modus mit HMAC-Validierung anzugeben, erstellen Sie eine Instanz von CngCbcAuthenticatedEncryptorConfiguration, die die Algorithmusinformationen enthält:

services.AddDataProtection()
    .UseCustomCryptographicAlgorithms(
        new CngCbcAuthenticatedEncryptorConfiguration()
    {
        // Passed to BCryptOpenAlgorithmProvider
        EncryptionAlgorithm = "AES",
        EncryptionAlgorithmProvider = null,

        // Specified in bits
        EncryptionAlgorithmKeySize = 256,

        // Passed to BCryptOpenAlgorithmProvider
        HashAlgorithm = "SHA256",
        HashAlgorithmProvider = null
    });

Hinweis

Der symmetrische Blockchiffre-Algorithmus muss eine Schlüssellänge von >= 128 Bit und eine Blockgröße von >= 64 Bit aufweisen und die Verschlüsselung im CBC-Modus mit PKCS #7-Auffüllung unterstützen. Der Hashalgorithmus muss eine Hashgröße von >= 128 Bit aufweisen und das Öffnen mit dem Flag BCRYPT_ALG_HANDLE_HMAC_FLAG unterstützen. Die *Provider-Eigenschaften können auf NULL festgelegt werden, um den Standardanbieter für den angegebenen Algorithmus zu verwenden. Weitere Informationen finden Sie in der Dokumentation zu BCryptOpenAlgorithmProvider.

Um einen benutzerdefinierten Windows-CNG-Algorithmus mithilfe der Verschlüsselung im Galois/Counter-Modus mit Validierung anzugeben, erstellen Sie eine Instanz von CngGcmAuthenticatedEncryptorConfiguration, die die Algorithmusinformationen enthält:

services.AddDataProtection()
    .UseCustomCryptographicAlgorithms(
        new CngGcmAuthenticatedEncryptorConfiguration()
    {
        // Passed to BCryptOpenAlgorithmProvider
        EncryptionAlgorithm = "AES",
        EncryptionAlgorithmProvider = null,

        // Specified in bits
        EncryptionAlgorithmKeySize = 256
    });

Hinweis

Der symmetrische Blockchiffre-Algorithmus muss eine Schlüssellänge von >= 128 Bit und eine Blockgröße von genau 128 Bit aufweisen und die GCM-Verschlüsselung unterstützen. Sie können die EncryptionAlgorithmProvider-Eigenschaft auf NULL festlegen, um den Standardanbieter für den angegebenen Algorithmus zu verwenden. Weitere Informationen finden Sie in der Dokumentation zu BCryptOpenAlgorithmProvider.

Angeben anderer benutzerdefinierter Algorithmen

Obwohl das Datenschutzsystem nicht als besondere API verfügbar gemacht wird, ist es erweiterbar genug, um die Angabe fast jeden Algorithmustyps zu ermöglichen. Es ist beispielsweise möglich, alle Schlüssel, die in einem Hardwaresicherheitsmodul (HSM) enthalten sind, beizubehalten und eine benutzerdefinierte Implementierung der wichtigsten Ver- und Entschlüsselungsroutinen bereitzustellen. Weitere Informationen finden Sie unter IAuthenticatedEncryptor in Kryptografieerweiterbarkeit in Core.

Beibehalten von Schlüsseln beim Hosten in einem Docker-Container

Beim Hosten in einem Docker-Container sollten Schlüssel mit einer der folgenden Optionen verwaltet werden:

  • In einem Ordner, der ein Docker-Volume ist, das über die Lebensdauer des Containers hinaus beibehalten wird, z. B. ein freigegebenes Volume oder ein vom Host bereitgestelltes Volume
  • Bei einem externen Anbieter, z. B. Azure Blob Storage (siehe Abschnitt ProtectKeysWithAzureKeyVault) oder Redis

Beibehalten von Schlüsseln mit Redis

Zum Speichern von Schlüsseln sollten nur Redis-Versionen verwendet werden, die Redis Data Persistence unterstützen. Azure Blob Storage ist persistent und kann zum Speichern von Schlüsseln verwendet werden. Weitere Informationen finden Sie in diesem GitHub-Issue.

Protokollieren des Datenschutzes

Aktivieren Sie die Protokollierung auf Information-Ebene von DataProtection, um die Diagnose von Problemen zu unterstützen. Die folgende Datei appsettings.json ermöglicht die Protokollierung auf Informationsebene der Datenschutz-API:

{
  "Logging": {
    "LogLevel": {
      "Microsoft.AspNetCore.DataProtection": "Information"
    }
  }
}

Weitere Informationen zur Protokollierung finden Sie unter Protokollieren in .NET Core und ASP.NET Core.

Zusätzliche Ressourcen