Partage via


Configurer la protection des données ASP.NET Core

Lorsque le système de protection des données est initialisé, il applique les paramètres par défaut en fonction de l’environnement opérationnel. Ces paramètres sont appropriés pour les applications s’exécutant sur un seul ordinateur. Toutefois, il existe des cas où un développeur peut vouloir modifier les paramètres par défaut :

  • L’application est répartie sur plusieurs ordinateurs.
  • Pour des raisons de conformité.

Pour ces scénarios, le système de protection des données offre une API de configuration riche.

Avertissement

Comme pour les fichiers de configuration, l’anneau de clés de protection des données doit être protégé à l’aide des autorisations appropriées. Vous pouvez choisir de chiffrer les clés au repos, mais cela n’empêche pas les cyber-attaques de créer de nouvelles clés. Par conséquent, la sécurité de votre application est affectée. L’emplacement de stockage configuré avec Data Protection doit avoir son accès limité à l’application elle-même, comme vous le feriez pour protéger les fichiers de configuration. Par exemple, si vous choisissez de stocker votre anneau de clés sur le disque, utilisez les autorisations du système de fichiers. Vérifiez que seule l’identité sous laquelle votre application web s’exécute a un accès en lecture, en écriture et en création à ce répertoire. Si vous utilisez Azure Blob Storage, seule l'application Web doit pouvoir lire, écrire ou créer de nouvelles entrées dans le magasin d'objets blob, etc.

La méthode d’extension AddDataProtection retourne un IDataProtectionBuilder. IDataProtectionBuilder expose les méthodes d’extension que vous pouvez chaîner ensemble pour configurer les options de protection des données.

Remarque

Cet article a été écrit pour une application qui fonctionne dans un conteneur Docker. Dans un conteneur Docker, l’application a toujours le même chemin et, par conséquent, le même discriminateur d’application. Les applications qui doivent être exécutées dans plusieurs environnements (par exemple, local et déployé) doivent définir le discriminateur d’application par défaut pour l’environnement. L’exécution d’une application dans plusieurs environnements dépasse le cadre de cet article.

Les packages NuGet suivants sont requis pour les extensions de protection des données utilisées dans cet article :

Protéger les clés avec Azure Key Vault (ProtectKeysWithAzureKeyVault)

Pour interagir avec Azure Key Vault localement à l’aide des informations d’identification du développeur, connectez-vous à votre compte de stockage dans Visual Studio ou connectez-vous avec Azure CLI. Si vous n’avez pas encore installé Azure CLI, consultez Comment installer Azure CLI. Vous pouvez exécuter la commande suivante dans le panneau Développeur PowerShell dans Visual Studio ou à partir d’un interpréteur de commandes quand vous n’utilisez pas Visual Studio :

az login

Pour plus d’informations, consultez Se connecter à Azure à l’aide des outils de développement.

Lorsque vous créez le coffre de clés dans le portail Entra ou Azure :

  • Configurez le coffre-fort de clés pour utiliser le contrôle d’accès basé sur les rôles Azure (RABC). Si vous n’utilisez pas de réseau virtuel Azure, notamment pour le développement et le test locaux, vérifiez que l’accès public à l’étape réseau est activé (activé). L’activation de l’accès public expose uniquement le point de terminaison du coffre-fort de clés. Les comptes authentifiés sont toujours requis pour l’accès.

  • Créez un rôle managé Azure Identity (ou ajoutez un rôle au rôle managé Identity existant que vous envisagez d'utiliser) avec le rôle Utilisateur chiffrement de Key Vault. Affectez le service managé Identity à l'Azure App Service qui héberge le déploiement : Paramètres>Identity>Utilisateur affecté>Ajouter.

    Remarque

    Si vous envisagez également d’exécuter une application localement avec un utilisateur autorisé pour l’accès aux objets blob à l’aide d’Azure CLI ou de l’authentification du service Azure de Visual Studio, ajoutez votre compte d’utilisateur Azure développeur dans Access Control (IAM) avec le rôle Utilisateur de chiffrement Key Vault . Si vous souhaitez utiliser Azure CLI via Visual Studio, exécutez la az login commande à partir du panneau Développeur PowerShell et suivez les invites pour vous authentifier auprès du locataire.

  • Lorsque le chiffrement de clé est actif, les clés du fichier de clé incluent le commentaire «This key is encrypted with Azure Key Vault. » Après avoir démarré l’application, sélectionnez la commande Affichage/modification dans le menu contextuel à la fin de la ligne de clé pour confirmer qu’une clé est présente avec la sécurité du coffre de clés appliquée.

  • Vous pouvez également activer la rotation automatique des clés du coffre de clés sans vous soucier de déchiffrer les charges utiles avec des clés de protection des données basées sur des clés de coffre de clés expirées/rotées. Chaque clé de protection des données générée inclut une référence à la clé de coffre de clés utilisée pour la chiffrer. Assurez-vous simplement de conserver les clés expirées dans l'Azure Key Vault, ne les supprimez pas. Utilisez également un identificateur de clé sans version dans la configuration du coffre de clés de l’application, où aucun GUID de clé n’est placé à la fin de l’identificateur (exemple : https://contoso.vault.azure.net/keys/data-protection). Utilisez une période de rotation similaire pour les deux clés, en veillant à ce que la clé de coffre de clés soit renouvelée plus souvent que la clé de protection des données pour garantir qu'une nouvelle clé de coffre de clés soit utilisée lors du renouvellement de la clé de protection des données.

La protection des clés avec Azure Key Vault implémente un IXmlEncryptor qui désactive les paramètres de protection automatique des données, y compris l’emplacement de stockage en anneau de clés. Pour configurer le fournisseur Azure Blob Storage afin de stocker les clés dans le stockage blob, suivez les instructions de la section Fournisseurs de stockage de clés dans ASP.NET Core et appelez l’une des surcharges PersistKeysToAzureBlobStorage dans l’application. L’exemple suivant utilise la surcharge qui accepte une URI de blob et des informations d’identification de jeton (TokenCredential), en s’appuyant sur un Identity géré par Azure pour le contrôle d’accès basé sur les rôles (RBAC).

Pour configurer le fournisseur Azure Key Vault, appelez l’une des surcharges ProtectKeysWithAzureKeyVault. L’exemple suivant utilise la surcharge qui accepte l’identifiant de clé et les informations d’identification du jeton (TokenCredential), en s’appuyant sur un Identity géré pour RBAC en production (ManagedIdentityCredential) ou un DefaultAzureCredential pendant le développement et les tests. D’autres surcharges acceptent soit un client Key Vault, soit un ID de client d’application avec un secret client. Pour plus d’informations, consultez Fournisseurs de stockage de clés dans ASP.NET Core.

Pour plus d’informations sur l’API et l’authentification du Kit de développement logiciel (SDK) Azure, consultez Authentifier les applications .NET auprès des services Azure à l’aide de la bibliothèque Azure Identity et fournir l’accès aux clés, certificats et secrets Key Vault avec le contrôle d’accès en fonction du rôle Azure. Pour obtenir des conseils de journalisation, consultez La journalisation avec le Kit de développement logiciel (SDK) Azure pour .NET : Journalisation sans inscription du client. Pour les applications utilisant l'injection de dépendances, une application peut appeler AddAzureClientsCore, en passant true pour enableLogForwarding, afin de créer et configurer l'infrastructure de journalisation.

Pour créer une clé dans le portail Azure, consultez Démarrage rapide : Définir et récupérer une clé à partir d’Azure Key Vault à l’aide du portail Azure. Donnez à la clé au moins les autorisations Get, Unwrap Key, et Wrap Key. Enregistrez l’identificateur de clé à utiliser avec la configuration de l’application. Si vous envisagez d’activer la rotation automatique de la clé de coffre de clés, enregistrez l’identificateur de clé sans version , où aucun GUID de clé n’est placé à la fin de l’identificateur (exemple : https://contoso.vault.azure.net/keys/data-protection).

Dans le Program fichier dans lequel les services sont inscrits :

TokenCredential? credential;

if (builder.Environment.IsProduction())
{
    credential = new ManagedIdentityCredential("{MANAGED IDENTITY CLIENT ID}");
}
else
{
    // Local development and testing only
    DefaultAzureCredentialOptions options = new()
    {
        // Specify the tenant ID to use the dev credentials when running the app locally
        // in Visual Studio.
        VisualStudioTenantId = "{TENANT ID}",
        SharedTokenCacheTenantId = "{TENANT ID}"
    };

    credential = new DefaultAzureCredential(options);
}

builder.Services.AddDataProtection()
    .SetApplicationName("{APPLICATION NAME}")
    .PersistKeysToAzureBlobStorage(new Uri("{BLOB URI}"), credential)
    .ProtectKeysWithAzureKeyVault(new Uri("{KEY IDENTIFIER}"), credential);

{MANAGED IDENTITY CLIENT ID} : ID client Azure Managed Identity (GUID).

{TENANT ID}: ID de locataire.

{APPLICATION NAME}: SetApplicationName définit le nom unique de cette application dans le système de protection des données. La valeur doit correspondre entre les déploiements de l’application.

{BLOB URI}: URI complet vers le fichier de clé. L’URI est généré par Stockage Azure lorsque vous créez le fichier de clé. N’utilisez pas de SAS.

{KEY IDENTIFIER}: identificateur de clé Azure Key Vault utilisé pour le chiffrement de clé. Une stratégie d’accès permet à l’application d’accéder au coffre de clés avec les autorisations Get, Unwrap Key, et Wrap Key. La version de la clé est obtenue à partir de la clé dans Entra ou le portail Azure après sa création. Si vous activez la rotation automatique de la clé de coffre de clés, veillez à utiliser un identificateur de clé sans version dans la configuration du coffre de clés de l’application, où aucun GUID de clé n’est placé à la fin de l’identificateur (exemple : https://contoso.vault.azure.net/keys/data-protection).

Pour qu’une application communique et s’autorise avec Azure Key Vault, le Azure.Identity package NuGet doit être référencé par l’application.

Remarque

Pour obtenir des conseils sur l'ajout de packages à des applications .NET, consultez les articles figurant sous Installer et gérer des packages dans Flux de travail de la consommation des packages (documentation NuGet). Vérifiez les versions du package sur NuGet.org.

Remarque

Dans les environnements hors production, l’exemple précédent utilise DefaultAzureCredential pour simplifier l’authentification lors du développement d’applications qui se déploient sur Azure en combinant les informations d’identification utilisées dans les environnements d’hébergement Azure avec les informations d’identification utilisées dans le développement local. Pour plus d’informations, consultez Authentifier les applications .NET hébergées par Azure auprès des ressources Azure à l’aide d’une identité managée affectée par le système.

Si l’application utilise les anciens packages Azure (Microsoft.AspNetCore.DataProtection.AzureStorageet Microsoft.AspNetCore.DataProtection.AzureKeyVault), nous vous recommandons de supprimer ces références et de les mettre à niveau vers les packages et Azure.Extensions.AspNetCore.DataProtection.Blobs les Azure.Extensions.AspNetCore.DataProtection.Keys packages. Les packages plus récents résolvent les problèmes de sécurité et de stabilité clés.

Approche alternative de signature d’accès partagé (SAS) : comme alternative à l’utilisation d’un Identity géré pour accéder au blob de clé dans le stockage Blob Azure, vous pouvez appeler la surcharge PersistKeysToAzureBlobStorage qui accepte une URI de blob avec un jeton SAS. L’exemple suivant continue d’utiliser une ManagedIdentityCredential (production) ou DefaultAzureCredential (développement et test) pour son TokenCredential, comme indiqué dans l’exemple précédent :

builder.Services.AddDataProtection()
    .SetApplicationName("{APPLICATION NAME}")
    .PersistKeysToAzureBlobStorage(new Uri("{BLOB URI WITH SAS}"))
    .ProtectKeysWithAzureKeyVault(new Uri("{KEY IDENTIFIER}"), credential);

{APPLICATION NAME}: SetApplicationName définit le nom unique de cette application dans le système de protection des données. La valeur doit correspondre entre les déploiements de l’application.

{BLOB URI WITH SAS}: URI complet où le fichier de clé doit être stocké avec le jeton SAP en tant que paramètre de chaîne de requête. L'URI est générée par Azure Storage lorsque vous demandez une SAS pour le fichier de clé téléchargé.

{KEY IDENTIFIER}: identificateur de clé Azure Key Vault utilisé pour le chiffrement de clé. Une stratégie d’accès permet à l’application d’accéder au coffre de clés avec les autorisations Get, Unwrap Key, et Wrap Key. La version de la clé est obtenue à partir de la clé dans Entra ou le portail Azure après sa création. Si vous activez la rotation automatique de la clé de coffre de clés, veillez à utiliser un identificateur de clé sans version dans la configuration du coffre de clés de l’application, où aucun GUID de clé n’est placé à la fin de l’identificateur (exemple : https://contoso.vault.azure.net/keys/data-protection).

Conserver les clés dans le système de fichiers (PersistKeysToFileSystem)

Pour stocker des clés sur un partage UNC au lieu de l’emplacement par défaut %LOCALAPPDATA%, configurez le système avec PersistKeysToFileSystem :

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

Avertissement

Si vous modifiez l’emplacement de persistance des clés, le système ne chiffre plus automatiquement les clés au repos, car il ne sait pas si DPAPI est un mécanisme de chiffrement approprié.

Conserver les clés dans une base de données (PersistKeysToDbContext)

Pour stocker des clés dans une base de données à l’aide d’EntityFramework, configurez le système avec le package Microsoft.AspNetCore.DataProtection.EntityFrameworkCore :

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

Le code précédent stocke les clés dans la base de données configurée. Le contexte de base de données utilisé doit implémenter IDataProtectionKeyContext. IDataProtectionKeyContext expose la propriété DataProtectionKeys

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

Cette propriété représente la table dans laquelle les clés sont stockées. Créez la table manuellement ou avec DbContext Migrations. Pour plus d’informations, consultez DataProtectionKey.

Protéger l’API de configuration des clés (ProtectKeysWith\*)

Vous pouvez configurer le système pour protéger les clés au repos en appelant l’une ProtectKeysWith\* des API de configuration. Prenons l’exemple ci-dessous, qui stocke les clés sur un partage UNC et chiffre ces clés au repos avec un certificat X.509 spécifique.

Vous pouvez fournir un X509Certificate2 à ProtectKeysWithCertificate à partir d’un fichier en appelant X509CertificateLoader.LoadCertificateFromFile:

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

L’exemple de code suivant montre comment charger un certificat à l’aide d’une empreinte numérique :

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

Vous pouvez fournir un X509Certificate2 à ProtectKeysWithCertificate, tel qu’un certificat chargé à partir d’un fichier :

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

L’exemple de code suivant montre comment charger un certificat à l’aide d’une empreinte numérique :

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

Pour obtenir des exemples et des discussions sur les mécanismes de chiffrement de clés intégrés, consultez Le chiffrement de clé au repos dans Windows et Azure à l’aide de ASP.NET Core.

Annuler la protection des clés avec n’importe quel certificat (UnprotectKeysWithAnyCertificate)

Vous pouvez faire pivoter des certificats et déchiffrer des clés au repos à l’aide d’un tableau de certificats X509Certificate2 avec UnprotectKeysWithAnyCertificate:

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"]));

Définir la durée de vie de la clé par défaut (SetDefaultKeyLifetime)

Pour configurer le système afin qu’il utilise une durée de vie de clé de 14 jours au lieu des 90 jours par défaut, utilisez SetDefaultKeyLifetime :

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

Définir le nom de l’application (SetApplicationName)

Par défaut, le système de protection des données isole les applications les unes des autres en fonction de leurs chemins racine de contenu, même si elles partagent le même référentiel de clés physiques. Cette isolation empêche les applications de comprendre les charges utiles protégées des autres.

Pour partager des charges utiles protégées entre les applications :

builder.Services.AddDataProtection()
    .SetApplicationName("<sharedApplicationName>");

SetApplicationName définit DataProtectionOptions.ApplicationDiscriminatoren interne. À des fins de résolution des problèmes, la valeur attribuée au discriminateur par le framework peut être journalisée avec le code suivant, placé après que WebApplication soit intégré dans Program.cs :

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

Pour plus d’informations sur l’utilisation du discriminateur, consultez les sections suivantes plus loin dans cet article :

Avertissement

Dans .NET 6, WebApplicationBuilder normalise le chemin racine du contenu pour qu'il se termine par un DirectorySeparatorChar. Par exemple, sur Windows, le chemin d’accès racine du contenu se termine par \ et sur Linux /. Les autres hôtes ne normalisent pas le chemin d’accès. La plupart des applications qui migrent à partir de HostBuilder ou WebHostBuilder ne partagent pas le même nom d’application, car elles n’auront pas le nom de fin DirectorySeparatorChar. Pour contourner ce problème, supprimez le caractère de séparateur de répertoire et définissez manuellement le nom de l’application, comme indiqué dans le code suivant :

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

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();

Désactiver la génération automatique de clés (DisableAutomaticKeyGeneration)

Vous pouvez avoir un scénario dans lequel vous ne souhaitez pas qu’une application effectue automatiquement une rotation des clés (crée de nouvelles clés) à l'approche de leur expiration. Un exemple de ce scénario peut être les applications configurées dans une relation primaire/secondaire, où seule l’application principale est responsable des problèmes de gestion des clés et où les applications secondaires ont simplement une vue en lecture seule de l’anneau de clés. Les applications secondaires peuvent être configurées pour traiter l’anneau de clés en lecture seule en configurant le système avec DisableAutomaticKeyGeneration :

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

Isolation par application

Lorsque le système de protection des données est fourni par un hôte ASP.NET Core, il isole automatiquement les applications les unes des autres, même si ces applications s’exécutent sous le même compte de processus de travail et utilisent le même master matériel de clé. Ceci est similaire au modificateur IsolateApps de l’élément <machineKey> System.Web.

Le mécanisme d’isolation fonctionne en considérant chaque application sur l’ordinateur local comme un locataire unique. Par conséquent, le IDataProtector rooté d’une application donnée inclut automatiquement l’ID d’application comme un discriminateur (ApplicationDiscriminator). L’ID unique de l’application est le chemin physique de l’application :

  • Pour les applications hébergées dans IIS, l’ID unique est le chemin physique IIS de l’application. Si une application est déployée dans un environnement de batterie de serveurs web, cette valeur est stable en supposant que les environnements IIS sont configurés de la même manière sur toutes les machines de la batterie de serveurs web.
  • Pour les applications auto-hébergées s’exécutant sur le Kestrel serveur, l’ID unique est le chemin physique de l’application sur le disque.

L’identificateur unique est conçu pour survivre aux réinitialisations, à la fois de l’application individuelle et de la machine elle-même.

Ce mécanisme d’isolation suppose que les applications ne sont pas malveillantes. Une application malveillante peut toujours avoir un impact sur toute autre application s’exécutant sous le même compte de processus de travail. Dans un environnement d’hébergement partagé où les applications ne sont pas approuvées mutuellement, le fournisseur d’hébergement doit prendre des mesures pour garantir l’isolation au niveau du système d’exploitation entre les applications, y compris la séparation des dépôts de clés sous-jacents des applications.

Si le système de protection des données n’est pas fourni par un hôte ASP.NET Core (par exemple, si vous l’instanciez via le type concret DataProtectionProvider), l’isolation de l’application est désactivée par défaut. Lorsque l’isolation d’application est désactivée, toutes les applications soutenues par le même matériel de clé peuvent partager des charges utiles tant qu’elles fournissent les objectifs appropriés. Pour fournir une isolation d’application dans cet environnement, appelez la méthode SetApplicationName sur l’objet de configuration et fournissez un nom unique pour chaque application.

Protection des données et isolation des applications

Tenez compte des points suivants pour l’isolation des applications :

  • Lorsque plusieurs applications sont dirigées vers le même référentiel de clés, l’intention est que les applications partagent le même matériau de clé maître. La protection des données est développée en supposant que toutes les applications partageant un anneau de clés peuvent accéder à tous les éléments de cet anneau de clés. L’identificateur unique de l’application est utilisé pour isoler les clés spécifiques à l’application dérivées des clés fournies par l’anneau de clés. Il ne s’attend pas à ce que les autorisations de niveau élément, telles que celles fournies par Azure KeyVault, soient utilisées pour appliquer une isolation supplémentaire. La tentative d’autorisations au niveau de l’élément génère des erreurs d’application. Si vous ne souhaitez pas vous fier à l’isolation intégrée de l’application, des emplacements de magasin de clés distincts doivent être utilisés et non partagés entre les applications.

  • Le discriminateur d’application (ApplicationDiscriminator) permet à différentes applications de partager le même matériel de clé principale, tout en conservant des charges utiles de chiffrement distinctes. Pour que les applications puissent lire les charges utiles de chiffrement de l’autre, elles doivent avoir le même discriminateur d’application, qui peut être défini en appelant SetApplicationName.

  • Si une application est compromise (par exemple, par une attaque RCE), tous les éléments de clé principale accessibles à cette application doivent également être considérés comme compromis, quel que soit son état de protection au repos. Cela implique que si deux applications sont pointées vers le même dépôt, même si elles utilisent des discriminateurs d’application différents, une compromission de l’une d’elles équivaut fonctionnellement à une compromission des deux.

    Cette clause « fonctionnellement équivalente à une compromission des deux » s'applique même si les deux applications utilisent des mécanismes différents pour la sécurité des clés en veille. En règle générale, il ne s’agit pas d’une configuration attendue. Le mécanisme de protection au repos est conçu pour offrir une protection dans le cas où un cyberattaquant parvient à avoir un accès en lecture au référentiel. Un cyberattaquant qui obtient un accès en écriture au dépôt (peut-être parce qu’il a obtenu l’autorisation d’exécution de code au sein d’une application) peut insérer des clés malveillantes dans le stockage. Le système de protection des données ne fournit intentionnellement pas de protection contre un cyberattaquant qui obtient un accès en écriture au dépôt de clés.

  • Si les applications doivent rester vraiment isolées les unes des autres, elles doivent utiliser différents référentiels de clés. Cela ne relève évidemment pas de la définition du terme « isolé ». Les applications ne sont pas isolées si elles disposent toutes d’un accès en lecture et en écriture aux magasins de données des autres.

Modification des algorithmes avec UseCryptographicAlgorithms

La pile de protection des données vous permet de modifier l’algorithme par défaut utilisé par les clés nouvellement générées. Le moyen le plus simple d’effectuer cette opération consiste à appeler UseCryptographicAlgorithms à partir du rappel de configuration :

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

Le EncryptionAlgorithm par défaut est AES-256-CBC, et l’élément ValidationAlgorithm par défaut est HMACSHA256. La stratégie par défaut peut être définie par un administrateur système via une stratégie à l’échelle de l’ordinateur, mais un appel explicite à UseCryptographicAlgorithms remplace la stratégie par défaut.

L’appel UseCryptographicAlgorithms vous permet de spécifier l’algorithme souhaité à partir d’une liste prédéfinie intégrée. Vous n’avez pas à vous soucier de l’implémentation de l’algorithme. Dans le scénario ci-dessus, le système de protection des données tente d’utiliser l’implémentation CNG d’AES en cas d’exécution sur Windows. Sinon, elle revient à la classe managée System.Security.Cryptography.Aes.

Vous pouvez spécifier manuellement une implémentation via un appel à UseCustomCryptographicAlgorithms.

Conseil

La modification des algorithmes n’affecte pas les clés existantes dans l’anneau de clés. Elle affecte uniquement les clés nouvellement générées.

Spécification d’algorithmes managés personnalisés

Pour spécifier des algorithmes managés personnalisés, créez une instance ManagedAuthenticatedEncryptorConfiguration qui pointe vers les types d’implémentation :

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)
    });

En règle générale, les propriétés *Type doivent pointer vers des implémentations concrètes et instanciables (via un constructeur public sans paramètre) de SymmetricAlgorithm et KeyedHashAlgorithm, bien que le système traite certaines valeurs comme typeof(Aes) comme des cas particuliers pour plus de commodité.

Remarque

SymmetricAlgorithm doit avoir une longueur de clé de ≥ 128 bits et une taille de bloc de ≥ 64 bits, et il doit prendre en charge le chiffrement en mode CBC avec remplissage PKCS #7. KeyedHashAlgorithm doit avoir une taille de synthèse de >= 128 bits, et il doit prendre en charge des clés de longueur égale à la longueur de synthèse de l’algorithme de hachage. KeyedHashAlgorithm n’est pas strictement requis pour être HMAC.

Spécification d’algorithmes CNG Windows personnalisés

Pour spécifier un algorithme CNG Windows personnalisé à l’aide du chiffrement en mode CBC avec validation HMAC, créez une instance CngCbcAuthenticatedEncryptorConfiguration qui contient les informations algorithmiques :

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
    });

Remarque

L’algorithme de chiffrement par blocs symétriques doit avoir une longueur de clé de >= 128 bits, une taille de bloc de >= 64 bits, et il doit prendre en charge le chiffrement en mode CBC avec remplissage PKCS #7. L'algorithme de hachage doit avoir une taille de synthèse de >= 128 bits et doit être compatible avec l'ouverture à l'aide du flag BCRYPT_ALG_HANDLE_HMAC_FLAG. Les propriétés du fournisseur peuvent être définies sur null pour utiliser le fournisseur par défaut pour l’algorithme spécifié. Pour plus d'informations, voir la documentation de BCryptOpenAlgorithmProvider.

Pour spécifier un algorithme CNG Windows personnalisé à l’aide du chiffrement Galois/Counter Mode avec validation, créez une instance CngGcmAuthenticatedEncryptorConfiguration qui contient les informations algorithmiques :

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

        // Specified in bits
        EncryptionAlgorithmKeySize = 256
    });

Remarque

L’algorithme de chiffrement par blocs symétriques doit avoir une longueur de clé de >= 128 bits, une taille de bloc d’exactement 128 bits, et il doit prendre en charge le chiffrement GCM. Vous pouvez définir la propriété EncryptionAlgorithmProvider sur null pour utiliser le fournisseur par défaut pour l’algorithme spécifié. Pour plus d'informations, voir la documentation de BCryptOpenAlgorithmProvider.

Spécification d’autres algorithmes personnalisés

Bien qu’il ne soit pas exposé en tant qu’API de première classe, le système de protection des données est suffisamment extensible pour permettre de spécifier presque n’importe quel type d’algorithme. Par exemple, il est possible de conserver toutes les clés contenues dans un module de sécurité matérielle (HSM) et de fournir une implémentation personnalisée des principales routines de chiffrement et de déchiffrement. Pour plus d’informations, consultez IAuthenticatedEncryptor dans Extensibilité de la cryptographie de base.

Persistance des clés lors de l'hébergement dans un conteneur Docker

Lors de l’hébergement dans un conteneur Docker, les clés doivent être conservées dans :

  • Un répertoire qui est un volume Docker persistant au-delà de la durée de vie du conteneur, tel qu'un volume partagé ou un volume monté sur un hôte.
  • Un fournisseur externe, tel que Stockage Blob Azure (illustré dans la section ProtectKeysWithAzureKeyVault) ou Redis.

Persistance des clés avec Redis

Seules les versions de Redis prenant en charge la persistance des données Redis doivent être utilisées pour stocker des clés. Le stockage Blob Azure est persistant et peut être utilisé pour stocker des clés. Pour plus d’informations, consultez ce problème GitHub.

Exploitation forestière

Activez le niveau Information ou inférieur de journalisation pour diagnostiquer les problèmes Le fichier suivant appsettings.json active la journalisation des informations de l’API Protection des données :

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

Pour plus d’informations sur la journalisation, consultez Journalisation dans .NET et ASP.NET Core.

Ressources supplémentaires

Lorsque le système de protection des données est initialisé, il applique les paramètres par défaut en fonction de l’environnement opérationnel. Ces paramètres sont appropriés pour les applications s’exécutant sur un seul ordinateur. Toutefois, il existe des cas où un développeur peut vouloir modifier les paramètres par défaut :

  • L’application est répartie sur plusieurs ordinateurs.
  • Pour des raisons de conformité.

Pour ces scénarios, le système de protection des données offre une API de configuration riche.

Avertissement

Comme pour les fichiers de configuration, l’anneau de clés de protection des données doit être protégé à l’aide des autorisations appropriées. Vous pouvez choisir de chiffrer les clés au repos, mais cela n’empêche pas les cyber-attaques de créer de nouvelles clés. Par conséquent, la sécurité de votre application est affectée. L’emplacement de stockage configuré avec Data Protection doit avoir son accès limité à l’application elle-même, comme vous le feriez pour protéger les fichiers de configuration. Par exemple, si vous choisissez de stocker votre anneau de clés sur le disque, utilisez les autorisations du système de fichiers. Vérifiez que seule l’identité sous laquelle votre application web s’exécute a un accès en lecture, en écriture et en création à ce répertoire. Si vous utilisez Azure Blob Storage, seule l'application web doit avoir la possibilité de lire, d'écrire ou de créer de nouvelles entrées dans le blob store.

La méthode d'extension AddDataProtection retourne un IDataProtectionBuilder, qui expose des méthodes d’extension que vous pouvez chaîner ensemble pour configurer les options de protection des données.

Les packages NuGet suivants sont requis pour les extensions de protection des données utilisées dans cet article :

Remarque

Pour obtenir des conseils sur l'ajout de packages à des applications .NET, consultez les articles figurant sous Installer et gérer des packages dans Flux de travail de la consommation des packages (documentation NuGet). Vérifiez les versions du package sur NuGet.org.

Protéger les clés avec Azure Key Vault (ProtectKeysWithAzureKeyVault)

Pour interagir avec Azure Key Vault localement à l’aide des informations d’identification du développeur, connectez-vous à votre compte de stockage dans Visual Studio ou connectez-vous avec Azure CLI. Si vous n’avez pas encore installé Azure CLI, consultez Comment installer Azure CLI. Vous pouvez exécuter la commande suivante dans le panneau Développeur PowerShell dans Visual Studio ou à partir d’un interpréteur de commandes quand vous n’utilisez pas Visual Studio :

az login

Pour plus d’informations, consultez Se connecter à Azure à l’aide des outils de développement.

Lorsque vous créez le coffre de clés dans le portail Entra ou Azure :

  • Configurez le coffre-fort de clés pour utiliser le contrôle d’accès basé sur les rôles Azure (RABC). Si vous n’utilisez pas de réseau virtuel Azure, notamment pour le développement et le test locaux, vérifiez que l’accès public à l’étape réseau est activé (activé). L’activation de l’accès public expose uniquement le point de terminaison du coffre-fort de clés. Les comptes authentifiés sont toujours requis pour l’accès.

  • Créez un rôle managé Azure Identity (ou ajoutez un rôle au rôle managé Identity existant que vous envisagez d'utiliser) avec le rôle Utilisateur chiffrement de Key Vault. Affectez le service managé Identity à l'Azure App Service qui héberge le déploiement : Paramètres>Identity>Utilisateur affecté>Ajouter.

    Remarque

    Si vous envisagez également d’exécuter une application localement avec un utilisateur autorisé pour l’accès aux objets blob à l’aide d’Azure CLI ou de l’authentification du service Azure de Visual Studio, ajoutez votre compte d’utilisateur Azure développeur dans Access Control (IAM) avec le rôle Utilisateur de chiffrement Key Vault . Si vous souhaitez utiliser Azure CLI via Visual Studio, exécutez la az login commande à partir du panneau Développeur PowerShell et suivez les invites pour vous authentifier auprès du locataire.

  • Lorsque le chiffrement de clé est actif, les clés du fichier de clé incluent le commentaire «This key is encrypted with Azure Key Vault. » Après avoir démarré l’application, sélectionnez la commande Affichage/modification dans le menu contextuel à la fin de la ligne de clé pour confirmer qu’une clé est présente avec la sécurité du coffre de clés appliquée.

  • Vous pouvez également activer la rotation automatique des clés du coffre de clés sans vous soucier de déchiffrer les charges utiles avec des clés de protection des données basées sur des clés de coffre de clés expirées/rotées. Chaque clé de protection des données générée inclut une référence à la clé de coffre de clés utilisée pour la chiffrer. Assurez-vous simplement de conserver les clés expirées dans l'Azure Key Vault, ne les supprimez pas. Utilisez également un identificateur de clé sans version dans la configuration du coffre de clés de l’application, où aucun GUID de clé n’est placé à la fin de l’identificateur (exemple : https://contoso.vault.azure.net/keys/data-protection). Utilisez une période de rotation similaire pour les deux clés, en veillant à ce que la clé de coffre de clés soit renouvelée plus souvent que la clé de protection des données pour garantir qu'une nouvelle clé de coffre de clés soit utilisée lors du renouvellement de la clé de protection des données.

La protection des clés avec Azure Key Vault implémente un IXmlEncryptor qui désactive les paramètres de protection automatique des données, y compris l’emplacement de stockage en anneau de clés. Pour configurer le fournisseur Azure Blob Storage afin de stocker les clés dans le stockage blob, suivez les instructions de la section Fournisseurs de stockage de clés dans ASP.NET Core et appelez l’une des surcharges PersistKeysToAzureBlobStorage dans l’application. L’exemple suivant utilise la surcharge qui accepte une URI de blob et des informations d’identification de jeton (TokenCredential), en s’appuyant sur un Identity géré par Azure pour le contrôle d’accès basé sur les rôles (RBAC).

Pour configurer le fournisseur Azure Key Vault, appelez l’une des surcharges ProtectKeysWithAzureKeyVault. L’exemple suivant utilise la surcharge qui accepte l’identifiant de clé et les informations d’identification du jeton (TokenCredential), en s’appuyant sur un Identity géré pour RBAC en production (ManagedIdentityCredential) ou un DefaultAzureCredential pendant le développement et les tests. D’autres surcharges acceptent soit un client Key Vault, soit un ID de client d’application avec un secret client. Pour plus d’informations, consultez Fournisseurs de stockage de clés dans ASP.NET Core.

Pour plus d’informations sur l’API et l’authentification du Kit de développement logiciel (SDK) Azure, consultez Authentifier les applications .NET auprès des services Azure à l’aide de la bibliothèque Azure Identity et fournir l’accès aux clés, certificats et secrets Key Vault avec le contrôle d’accès en fonction du rôle Azure. Pour obtenir des conseils de journalisation, consultez La journalisation avec le Kit de développement logiciel (SDK) Azure pour .NET : Journalisation sans inscription du client. Pour les applications utilisant l'injection de dépendances, une application peut appeler AddAzureClientsCore, en passant true pour enableLogForwarding, afin de créer et configurer l'infrastructure de journalisation.

Pour créer une clé dans le portail Azure, consultez Démarrage rapide : Définir et récupérer une clé à partir d’Azure Key Vault à l’aide du portail Azure. Donnez à la clé au moins les autorisations Get, Unwrap Key, et Wrap Key. Enregistrez l’identificateur de clé à utiliser avec la configuration de l’application. Si vous envisagez d’activer la rotation automatique de la clé de coffre de clés, enregistrez l’identificateur de clé sans version , où aucun GUID de clé n’est placé à la fin de l’identificateur (exemple : https://contoso.vault.azure.net/keys/data-protection).

Dans le Program fichier dans lequel les services sont inscrits :

TokenCredential? credential;

if (builder.Environment.IsProduction())
{
    credential = new ManagedIdentityCredential("{MANAGED IDENTITY CLIENT ID}");
}
else
{
    // Local development and testing only
    DefaultAzureCredentialOptions options = new()
    {
        // Specify the tenant ID to use the dev credentials when running the app locally
        // in Visual Studio.
        VisualStudioTenantId = "{TENANT ID}",
        SharedTokenCacheTenantId = "{TENANT ID}"
    };

    credential = new DefaultAzureCredential(options);
}

services.AddDataProtection()
    .SetApplicationName("{APPLICATION NAME}")
    .PersistKeysToAzureBlobStorage(new Uri("{BLOB URI}"), credential)
    .ProtectKeysWithAzureKeyVault(new Uri("{KEY IDENTIFIER}"), credential);

{MANAGED IDENTITY CLIENT ID} : ID client Azure Managed Identity (GUID).

{TENANT ID}: ID de locataire.

{APPLICATION NAME}: SetApplicationName définit le nom unique de cette application dans le système de protection des données. La valeur doit correspondre entre les déploiements de l’application.

{BLOB URI}: URI complet vers le fichier de clé. L’URI est généré par Stockage Azure lorsque vous créez le fichier de clé. N’utilisez pas de SAS.

{KEY IDENTIFIER}: identificateur de clé Azure Key Vault utilisé pour le chiffrement de clé. Une stratégie d’accès permet à l’application d’accéder au coffre de clés avec les autorisations Get, Unwrap Key, et Wrap Key. La version de la clé est obtenue à partir de la clé dans Entra ou le portail Azure après sa création. Si vous activez la rotation automatique de la clé de coffre de clés, veillez à utiliser un identificateur de clé sans version dans la configuration du coffre de clés de l’application, où aucun GUID de clé n’est placé à la fin de l’identificateur (exemple : https://contoso.vault.azure.net/keys/data-protection).

Pour qu’une application communique et s’autorise avec Azure Key Vault, le Azure.Identity package NuGet doit être référencé par l’application.

Remarque

Pour obtenir des conseils sur l'ajout de packages à des applications .NET, consultez les articles figurant sous Installer et gérer des packages dans Flux de travail de la consommation des packages (documentation NuGet). Vérifiez les versions du package sur NuGet.org.

Remarque

Dans les environnements hors production, l’exemple précédent utilise DefaultAzureCredential pour simplifier l’authentification lors du développement d’applications qui se déploient sur Azure en combinant les informations d’identification utilisées dans les environnements d’hébergement Azure avec les informations d’identification utilisées dans le développement local. Pour plus d’informations, consultez Authentifier les applications .NET hébergées par Azure auprès des ressources Azure à l’aide d’une identité managée affectée par le système.

Si l’application utilise les anciens packages Azure (Microsoft.AspNetCore.DataProtection.AzureStorageet Microsoft.AspNetCore.DataProtection.AzureKeyVault), nous vous recommandons de supprimer ces références et de les mettre à niveau vers les packages et Azure.Extensions.AspNetCore.DataProtection.Blobs les Azure.Extensions.AspNetCore.DataProtection.Keys packages. Les packages plus récents résolvent les problèmes de sécurité et de stabilité clés.

Approche alternative de signature d’accès partagé (SAS) : comme alternative à l’utilisation d’un Identity géré pour accéder au blob de clé dans le stockage Blob Azure, vous pouvez appeler la surcharge PersistKeysToAzureBlobStorage qui accepte une URI de blob avec un jeton SAS. L’exemple suivant continue d’utiliser une ManagedIdentityCredential (production) ou DefaultAzureCredential (développement et test) pour son TokenCredential, comme indiqué dans l’exemple précédent :

services.AddDataProtection()
    .SetApplicationName("{APPLICATION NAME}")
    .PersistKeysToAzureBlobStorage(new Uri("{BLOB URI WITH SAS}"))
    .ProtectKeysWithAzureKeyVault(new Uri("{KEY IDENTIFIER}"), credential);

{APPLICATION NAME}: SetApplicationName définit le nom unique de cette application dans le système de protection des données. La valeur doit correspondre entre les déploiements de l’application.

{BLOB URI WITH SAS}: URI complet où le fichier de clé doit être stocké avec le jeton SAP en tant que paramètre de chaîne de requête. L'URI est générée par Azure Storage lorsque vous demandez une SAS pour le fichier de clé téléchargé.

{KEY IDENTIFIER}: identificateur de clé Azure Key Vault utilisé pour le chiffrement de clé. Une stratégie d’accès permet à l’application d’accéder au coffre de clés avec les autorisations Get, Unwrap Key, et Wrap Key. La version de la clé est obtenue à partir de la clé dans Entra ou le portail Azure après sa création. Si vous activez la rotation automatique de la clé de coffre de clés, veillez à utiliser un identificateur de clé sans version dans la configuration du coffre de clés de l’application, où aucun GUID de clé n’est placé à la fin de l’identificateur (exemple : https://contoso.vault.azure.net/keys/data-protection).

Conserver les clés dans le système de fichiers (PersistKeysToFileSystem)

Pour stocker des clés sur un partage UNC au lieu de l’emplacement par défaut %LOCALAPPDATA%, configurez le système avec PersistKeysToFileSystem :

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

Avertissement

Si vous modifiez l’emplacement de persistance des clés, le système ne chiffre plus automatiquement les clés au repos, car il ne sait pas si DPAPI est un mécanisme de chiffrement approprié.

Conserver les clés dans une base de données (PersistKeysToDbContext)

Pour stocker des clés dans une base de données à l’aide d’EntityFramework, configurez le système avec le package Microsoft.AspNetCore.DataProtection.EntityFrameworkCore :

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

Le code précédent stocke les clés dans la base de données configurée. Le contexte de base de données utilisé doit implémenter IDataProtectionKeyContext. IDataProtectionKeyContext expose la propriété DataProtectionKeys

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

Cette propriété représente la table dans laquelle les clés sont stockées. Créez la table manuellement ou avec DbContext Migrations. Pour plus d’informations, consultez DataProtectionKey.

Protéger l’API de configuration des clés (ProtectKeysWith\*)

Vous pouvez configurer le système pour protéger les clés au repos en appelant l’une ProtectKeysWith\* des API de configuration. Prenons l’exemple ci-dessous, qui stocke les clés sur un partage UNC et chiffre ces clés au repos avec un certificat X.509 spécifique :

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

Vous pouvez fournir un X509Certificate2 à ProtectKeysWithCertificate, tel qu’un certificat chargé à partir d’un fichier :

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

Pour plus d’exemples et de discussions sur les mécanismes de chiffrement de clés intégrés, consultez Le chiffrement de clé au repos dans Windows et Azure à l’aide de ASP.NET Core.

Annuler la protection des clés avec n’importe quel certificat (UnprotectKeysWithAnyCertificate)

Vous pouvez faire pivoter des certificats et déchiffrer des clés au repos à l’aide d’un tableau de certificats X509Certificate2 avec UnprotectKeysWithAnyCertificate:

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"]));
}

Définir la durée de vie de la clé par défaut (SetDefaultKeyLifetime)

Pour configurer le système afin qu’il utilise une durée de vie de clé de 14 jours au lieu des 90 jours par défaut, utilisez SetDefaultKeyLifetime :

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

Définir le nom de l’application (SetApplicationName)

Par défaut, le système de protection des données isole les applications les unes des autres en fonction de leurs chemins racine de contenu, même si elles partagent le même référentiel de clés physiques. Cette isolation empêche les applications de comprendre les charges utiles protégées des autres.

Pour partager des charges utiles protégées entre les applications :

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .SetApplicationName("{APPLICATION NAME}");
}

SetApplicationName définit DataProtectionOptions.ApplicationDiscriminatoren interne. Pour plus d’informations sur l’utilisation du discriminateur, consultez les sections suivantes plus loin dans cet article :

Désactiver la génération automatique de clés (DisableAutomaticKeyGeneration)

Vous pouvez avoir un scénario dans lequel vous ne souhaitez pas qu’une application effectue automatiquement une rotation des clés (crée de nouvelles clés) à l'approche de leur expiration. Un exemple de ce scénario peut être les applications configurées dans une relation primaire/secondaire, où seule l’application principale est responsable des problèmes de gestion des clés et où les applications secondaires ont simplement une vue en lecture seule de l’anneau de clés. Les applications secondaires peuvent être configurées pour traiter l’anneau de clés en lecture seule en configurant le système avec DisableAutomaticKeyGeneration :

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

Isolation par application

Lorsque le système de protection des données est fourni par un hôte ASP.NET Core, il isole automatiquement les applications les unes des autres, même si ces applications s’exécutent sous le même compte de processus de travail et utilisent le même master matériel de clé. Ceci est similaire au modificateur IsolateApps de l’élément <machineKey> System.Web.

Le mécanisme d’isolation fonctionne en considérant chaque application sur l’ordinateur local comme un locataire unique. Par conséquent, le IDataProtector rooté d’une application donnée inclut automatiquement l’ID d’application comme un discriminateur (ApplicationDiscriminator). L’ID unique de l’application est le chemin physique de l’application :

  • Pour les applications hébergées dans IIS, l’ID unique est le chemin physique IIS de l’application. Si une application est déployée dans un environnement de batterie de serveurs web, cette valeur est stable en supposant que les environnements IIS sont configurés de la même manière sur toutes les machines de la batterie de serveurs web.
  • Pour les applications auto-hébergées s’exécutant sur le Kestrel serveur, l’ID unique est le chemin physique de l’application sur le disque.

L’identificateur unique est conçu pour survivre aux réinitialisations, à la fois de l’application individuelle et de la machine elle-même.

Ce mécanisme d’isolation suppose que les applications ne sont pas malveillantes. Une application malveillante peut toujours avoir un impact sur toute autre application s’exécutant sous le même compte de processus de travail. Dans un environnement d’hébergement partagé où les applications ne sont pas approuvées mutuellement, le fournisseur d’hébergement doit prendre des mesures pour garantir l’isolation au niveau du système d’exploitation entre les applications, y compris la séparation des dépôts de clés sous-jacents des applications.

Si le système de protection des données n’est pas fourni par un hôte ASP.NET Core (par exemple, si vous l’instanciez via le type concret DataProtectionProvider), l’isolation de l’application est désactivée par défaut. Lorsque l’isolation d’application est désactivée, toutes les applications soutenues par le même matériel de clé peuvent partager des charges utiles tant qu’elles fournissent les objectifs appropriés. Pour fournir une isolation d’application dans cet environnement, appelez la méthode SetApplicationName sur l’objet de configuration et fournissez un nom unique pour chaque application.

Protection des données et isolation des applications

Tenez compte des points suivants pour l’isolation des applications :

  • Lorsque plusieurs applications sont dirigées vers le même référentiel de clés, l’intention est que les applications partagent le même matériau de clé maître. La protection des données est développée en supposant que toutes les applications partageant un anneau de clés peuvent accéder à tous les éléments de cet anneau de clés. L’identificateur unique de l’application est utilisé pour isoler les clés spécifiques à l’application dérivées des clés fournies par l’anneau de clés. Il ne s’attend pas à ce que les autorisations de niveau élément, telles que celles fournies par Azure KeyVault, soient utilisées pour appliquer une isolation supplémentaire. La tentative d’autorisations au niveau de l’élément génère des erreurs d’application. Si vous ne souhaitez pas vous fier à l’isolation intégrée de l’application, des emplacements de magasin de clés distincts doivent être utilisés et non partagés entre les applications.

  • Le discriminateur d’application (ApplicationDiscriminator) permet à différentes applications de partager le même matériel de clé principale, tout en conservant des charges utiles de chiffrement distinctes. Pour que les applications puissent lire les charges utiles de chiffrement de l’autre, elles doivent avoir le même discriminateur d’application, qui peut être défini en appelant SetApplicationName.

  • Si une application est compromise (par exemple, par une attaque RCE), tous les éléments de clé principale accessibles à cette application doivent également être considérés comme compromis, quel que soit son état de protection au repos. Cela implique que si deux applications sont pointées vers le même dépôt, même si elles utilisent des discriminateurs d’application différents, une compromission de l’une d’elles équivaut fonctionnellement à une compromission des deux.

    Cette clause « fonctionnellement équivalente à une compromission des deux » s'applique même si les deux applications utilisent des mécanismes différents pour la sécurité des clés en veille. En règle générale, il ne s’agit pas d’une configuration attendue. Le mécanisme de protection au repos est conçu pour offrir une protection dans le cas où un cyberattaquant parvient à avoir un accès en lecture au référentiel. Un cyberattaquant qui obtient un accès en écriture au dépôt (peut-être parce qu’il a obtenu l’autorisation d’exécution de code au sein d’une application) peut insérer des clés malveillantes dans le stockage. Le système de protection des données ne fournit intentionnellement pas de protection contre un cyberattaquant qui obtient un accès en écriture au dépôt de clés.

  • Si les applications doivent rester vraiment isolées les unes des autres, elles doivent utiliser différents référentiels de clés. Cela ne relève évidemment pas de la définition du terme « isolé ». Les applications ne sont pas isolées si elles disposent toutes d’un accès en lecture et en écriture aux magasins de données des autres.

Modification des algorithmes avec UseCryptographicAlgorithms

La pile de protection des données vous permet de modifier l’algorithme par défaut utilisé par les clés nouvellement générées. Le moyen le plus simple d’effectuer cette opération consiste à appeler UseCryptographicAlgorithms à partir du rappel de configuration :

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

Le EncryptionAlgorithm par défaut est AES-256-CBC, et l’élément ValidationAlgorithm par défaut est HMACSHA256. La stratégie par défaut peut être définie par un administrateur système via une stratégie à l’échelle de l’ordinateur, mais un appel explicite à UseCryptographicAlgorithms remplace la stratégie par défaut.

L’appel UseCryptographicAlgorithms vous permet de spécifier l’algorithme souhaité à partir d’une liste prédéfinie intégrée. Vous n’avez pas à vous soucier de l’implémentation de l’algorithme. Dans le scénario ci-dessus, le système de protection des données tente d’utiliser l’implémentation CNG d’AES en cas d’exécution sur Windows. Sinon, elle revient à la classe managée System.Security.Cryptography.Aes.

Vous pouvez spécifier manuellement une implémentation via un appel à UseCustomCryptographicAlgorithms.

Conseil

La modification des algorithmes n’affecte pas les clés existantes dans l’anneau de clés. Elle affecte uniquement les clés nouvellement générées.

Spécification d’algorithmes managés personnalisés

Pour spécifier des algorithmes managés personnalisés, créez une instance ManagedAuthenticatedEncryptorConfiguration qui pointe vers les types d’implémentation :

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)
    });

En règle générale, les propriétés *Type doivent pointer vers des implémentations concrètes et instanciables (via un constructeur public sans paramètre) de SymmetricAlgorithm et KeyedHashAlgorithm, bien que le système traite certaines valeurs comme typeof(Aes) comme des cas particuliers pour plus de commodité.

Remarque

SymmetricAlgorithm doit avoir une longueur de clé de ≥ 128 bits et une taille de bloc de ≥ 64 bits, et il doit prendre en charge le chiffrement en mode CBC avec remplissage PKCS #7. KeyedHashAlgorithm doit avoir une taille de synthèse de >= 128 bits, et il doit prendre en charge des clés de longueur égale à la longueur de synthèse de l’algorithme de hachage. KeyedHashAlgorithm n’est pas strictement requis pour être HMAC.

Spécification d’algorithmes CNG Windows personnalisés

Pour spécifier un algorithme CNG Windows personnalisé à l’aide du chiffrement en mode CBC avec validation HMAC, créez une instance CngCbcAuthenticatedEncryptorConfiguration qui contient les informations algorithmiques :

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

        // Specified in bits
        EncryptionAlgorithmKeySize = 256,

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

Remarque

L’algorithme de chiffrement par blocs symétriques doit avoir une longueur de clé de >= 128 bits, une taille de bloc de >= 64 bits, et il doit prendre en charge le chiffrement en mode CBC avec remplissage PKCS #7. L'algorithme de hachage doit avoir une taille de synthèse de >= 128 bits et doit être compatible avec l'ouverture à l'aide du flag BCRYPT_ALG_HANDLE_HMAC_FLAG. Les propriétés du fournisseur peuvent être définies sur null pour utiliser le fournisseur par défaut pour l’algorithme spécifié. Pour plus d'informations, voir la documentation de BCryptOpenAlgorithmProvider.

Pour spécifier un algorithme CNG Windows personnalisé à l’aide du chiffrement Galois/Counter Mode avec validation, créez une instance CngGcmAuthenticatedEncryptorConfiguration qui contient les informations algorithmiques :

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

        // Specified in bits
        EncryptionAlgorithmKeySize = 256
    });

Remarque

L’algorithme de chiffrement par blocs symétriques doit avoir une longueur de clé de >= 128 bits, une taille de bloc d’exactement 128 bits, et il doit prendre en charge le chiffrement GCM. Vous pouvez définir la propriété EncryptionAlgorithmProvider sur null pour utiliser le fournisseur par défaut pour l’algorithme spécifié. Pour plus d'informations, voir la documentation de BCryptOpenAlgorithmProvider.

Spécification d’autres algorithmes personnalisés

Bien qu’il ne soit pas exposé en tant qu’API de première classe, le système de protection des données est suffisamment extensible pour permettre de spécifier presque n’importe quel type d’algorithme. Par exemple, il est possible de conserver toutes les clés contenues dans un module de sécurité matérielle (HSM) et de fournir une implémentation personnalisée des principales routines de chiffrement et de déchiffrement. Pour plus d’informations, consultez IAuthenticatedEncryptor dans Extensibilité de la cryptographie de base.

Persistance des clés lors de l'hébergement dans un conteneur Docker

Lors de l’hébergement dans un conteneur Docker, les clés doivent être conservées dans :

Persistance des clés avec Redis

Seules les versions de Redis prenant en charge la persistance des données Redis doivent être utilisées pour stocker des clés. Le stockage Blob Azure est persistant et peut être utilisé pour stocker des clés. Pour plus d’informations, consultez ce problème GitHub.

Exploitation forestière

Activez le niveau Information ou inférieur de journalisation pour diagnostiquer les problèmes Le fichier suivant appsettings.json active la journalisation des informations de l’API Protection des données :

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

Pour plus d’informations sur la journalisation, consultez Journalisation dans .NET et ASP.NET Core.

Ressources supplémentaires