web-dev-qa-db-fra.com

Cryptage/décryptage sécurisé de appsettings.json sur le serveur

Comment protéger la clé de chiffrement utilisée pour chiffrer les données sensibles dans le appsettings.json de mon application Web?

Je souhaite protéger les données sensibles dans la configuration de mon application Web.

Dans les applications ASP.NET MVC4, nous l’avons fait comme ceci:

  1. Les données sensibles (par exemple, mot de passe dans une chaîne de connexion) ne sont pas ajoutées directement à web.config (ou web.prod.config etc.), mais une variable d'espace réservé est écrite.
  2. Au moment du déploiement, notre service de déploiement (Octopus) récupèrerait des données sensibles de son stockage sécurisé et écraserait la variable dans le web.config.
  3. Le processus de déploiement chiffrerait ensuite les sections sensibles de web.config à l'aide de aspnet_regiis.exe.

Maintenant, nous utilisons ASP.NET Core, le processus que nous suivons est un peu différent.

  1. appsettings.json contient les variables de substitution pour les données sensibles, similaires au fonctionnement de web.config.
  2. Le processus de déploiement substitue les espaces réservés aux données sensibles de son magasin sécurisé, comme auparavant.
  3. Au lieu d’utiliser aspnet_regiis, j’ai besoin de:

    a) créer mon propre outil personnalisé pour chiffrer des parties du fichier appsettings.json.

    b) créer un fournisseur de configuration personnalisé capable de décrypter (tout/partie du) le appsettings.json

Ce que je ne comprends pas, c'est comment protéger la clé de chiffrement utilisée pour (a) et (b). L'ancien moyen utilisait la clé machine du serveur pour chiffrer le fichier. 

La menace que j'essaie d'atténuer est que quelqu'un ait accès au appsettings.json sur le serveur et en lise des données sensibles (par exemple, mot de passe de la base de données, etc.).

Je suis également intéressé par d'autres moyens d'atténuer cette menace et/ou d'autres problèmes avec cette approche en général.

8
Ergwun

Si vous ne faites pas confiance au serveur, vous ne pouvez pas protéger les "secrets" que vous stockez à l'intérieur de ce serveur.

Explication:

Peu importe le schéma "sécurisé" (= non sécurisé) que vous inventez - lorsque l'application démarre, vous devez être capable de "décrypter" les secrets sous une forme "utilisable".

Cela signifie que toutes les "clés" (certificats, etc.) requises pour "décrypter" doivent exister sur ce serveur et être accessibles à l'application (sinon, l'application ne peut pas démarrer).

Cela signifie que certains méchants qui accèdent au serveur et à l'application peuvent également accéder à toutes les "clés" et "déchiffrer" vos secrets. Peut-être en copiant des fichiers, en décompilant votre application, en déchargeant éventuellement la mémoire de votre application, mais ce peut être le cas.

Il n'y a pas de protection absolue.

2
Dmitry

Il semble que vous ne soyez pas intéressé par les "moyens" de le faire, mais par l'approche recommandée par ASP.NET Core. Tandis que d'autres réponses ici mentionnées mentionnent Azure KeyVault comme un bon stockage pour les informations sensibles, ce n'est pas le moyen de le stocker, mais plutôt le stockage réel . ASP.NET Core prend en charge la notion de overridable configuration. C'est-à-dire que plusieurs fournisseurs de configuration peuvent être enregistrés dans le système de configuration et l'ordre dans lequel ils sont enregistrés. Chaque personne enregistrée remplace les paramètres des fournisseurs précédents - ceux qu’il a bien sûr ..... En d’autres termes, si vous avez enregistré le fournisseur de configuration JSON standard, puis supposons également un fournisseur de configuration de base de données, puis ces paramètres, que les deux fournisseurs ont, obtiendra les valeurs définies par le fournisseur défini plus tard - le fournisseur de base de données . Donc, dans votre situation, voici ce que je suggérerais de faire:

  1. Avoir tous les fournisseurs de configuration par défaut enregistrés comme est.
  2. Enregistrez le fournisseur de configuration Azure Key Vault (ou un fournisseur similaire basé sur un stockage secret) à la fin.
  3. Utilisez l'authentification par certificat pour vous authentifier avec Key Vault et lire les paramètres sensibles.

Bien qu'il ne s'agisse pas d'un mappage 1: 1 de votre processus actuel, il est conforme aux principes de base d'ASP.NET.

Vous pouvez en savoir plus sur la configuration ASP.NET à l’adresse: https://docs.Microsoft.com/en-us/aspnet/core/fundamentals/configuration/index?tabs=basicconfiguration

Vous trouverez ici des informations sur le fournisseur de configuration Azure KeyVault: https://docs.Microsoft.com/en-us/aspnet/core/security/key-vault-configuration?tabs=aspnetcore2x

Si l'authentification par certificat n'est pas une option pour vous, envisagez de stocker les variables ClientId et ClientSecret utilisées pour vous connecter au service Azure Key Vault dans des variables d'environnement, et utilisez un fournisseur de configuration approprié (la méthode d'extension AddEnvironmentVariables() le fera) pour y accéder.

Cette configuration sera vraiment sécurisée. Bonne chance!

2
Artak

Si une personne non autorisée accède au serveur, eh bien, voler les secrets - par exemple, les chaînes de connexion à la base de données, n’est qu’une petite partie du problème (réponse de @Dmitry).

Etant donné que vous souhaitez mieux contrôler les données secrètes ou la configuration, il convient de s'écarter légèrement de l'approche okay par rapport à l'approche habituelleappsettings.json-.

Vous pouvez prendre les secrets, les chiffrer de manière asymétrique avec le certificat du serveur, les stocker dans un fichier séparé (il peut s'agir d'un autre fichier .json), puis lire le fichier et déchiffrer les secrets au démarrage/à chaque demande Web. De cette façon, les secrets sont presque aussi sûrs que le certificat/la clé privée du serveur.

Une autre option: chiffrer les secrets de manière symétrique et transmettre le mot de passe à l'application Web au démarrage afin qu'elle puisse déchiffrer les secrets. Lorsque le processus hébergeant l'application Web redémarre, vous devez saisir le mot de passe à nouveau (vous pouvez utiliser une machine distincte pour le charger régulièrement).

Voir également Protection des données dans ASP.NET Core , Exemples de protection des données .

Parfois, des mots de passe longs et cryptés ou la simple dissimulation d'un mot de passe par ailleurs convivial, suffisent. C’est-à-dire protéger uniquement contre l’écoute. Disons, quelqu'un assis à côté de l'administrateur ne sera pas capable de lire et de mémoriser une chaîne de caractères apparemment aléatoires.

1
turdus-merula

Je convertis le commentaire en réponse :)

Même si vous ne travaillez pas sur Azure, je vous recommanderais quand même d'utiliser Azure Key Vault pour stocker vos secrets. Pour commencer, il est très bon marché (environ 0,0159 USD/10 000 opérations) et deuxièmement, il est accessible depuis n’importe où, même en dehors d’Azure. De plus, les secrets d’Azure Key Vault peuvent faire l’objet de versions, ce qui est une fonctionnalité intéressante permettant de prendre en charge plusieurs versions d’un secret par environnement (uniquement pour la pré-production, car Production doit disposer de son propre coffre-fort). Key Vault NuGet package contient des opérations permettant de récupérer et d’ajouter des secrets dans .NET Core. Ici est un lien vers la documentation.

Vous pouvez avoir un cache en mémoire afin qu'un appel REST (ou un appel de méthode de package Key Vault) à Key Vault soit effectué uniquement au début de votre application (ou à l'expiration de votre cache), évitant ainsi toute latence supplémentaire. Troisièmement, c'est l'approche recommandée par Microsoft.

J'espère que cela t'aides.

1
ThePretendProgrammer