[c#] SecureString est-il toujours pratique dans une application C #?



2 Answers

Les quelques problèmes dans vos hypothèses.

Tout d'abord, la classe SecureString n'a pas de constructeur String. Pour en créer un, vous allouez un objet puis ajoutez les caractères.

Dans le cas d'une interface graphique ou d'une console, vous pouvez très facilement passer chaque touche enfoncée à une chaîne sécurisée.

La classe est conçue de telle sorte que vous ne pouvez pas, par erreur, accéder à la valeur stockée. Cela signifie que vous ne pouvez pas obtenir la string directement en tant que mot de passe.

Donc, pour l'utiliser, par exemple, pour authentifier via le web, vous devrez utiliser des classes appropriées qui sont également sécurisées.

Dans le framework .NET, vous avez quelques classes qui peuvent utiliser SecureString

  • Le contrôle PasswordBox de WPF conserve le mot de passe en tant que SecureString en interne.
  • La propriété Password de System.Diagnostics.ProcessInfo est un SecureString.
  • Le constructeur de X509Certificate2 prend un SecureString pour le mot de passe.

(more)

En conclusion, la classe SecureString peut être utile, mais nécessite plus d'attention de la part du développeur.

Tout ceci, avec des exemples, est bien décrit dans la documentation MSDN de SecureString

Question

N'hésitez pas à me corriger si mes hypothèses sont fausses ici, mais laissez-moi vous expliquer pourquoi je demande.

Pris à partir de MSDN, un SecureString :

Représente le texte qui devrait rester confidentiel. Le texte est crypté pour la confidentialité lorsqu'il est utilisé et supprimé de la mémoire de l'ordinateur lorsqu'il n'est plus nécessaire.

Je comprends cela, il est tout à fait logique de stocker un mot de passe ou d'autres informations privées dans un SecureString sur un System.String , parce que vous pouvez contrôler comment et quand il est réellement stocké en mémoire, car un System.String :

est à la fois immuable et, lorsqu'il n'est plus nécessaire, ne peut pas être programmé par programmation pour la récupération de place; c'est-à-dire que l'instance est en lecture seule après sa création et qu'il n'est pas possible de prédire quand l'instance sera supprimée de la mémoire de l'ordinateur. Par conséquent, si un objet String contient des informations sensibles telles qu'un mot de passe, un numéro de carte de crédit ou des données personnelles, les informations risquent d'être révélées après leur utilisation car votre application ne peut pas supprimer les données de la mémoire de l'ordinateur.

Cependant, dans le cas d'une application GUI (par exemple, un client ssh), le SecureString doit être construit à partir d'un System.String . Tous les contrôles de texte utilisent une chaîne comme type de données sous-jacent .

Cela signifie que chaque fois que l'utilisateur appuie sur une touche, l'ancienne chaîne existante est supprimée et une nouvelle chaîne est créée pour représenter la valeur dans la zone de texte, même si vous utilisez un masque de mot de passe. Et nous ne pouvons pas contrôler quand ou si l'une de ces valeurs est supprimée de la mémoire .

Il est maintenant temps de vous connecter au serveur. Devine quoi? Vous devez passer une chaîne sur la connexion pour l'authentification . Alors convertissons notre SecureString en un System.String .... et maintenant nous avons une chaîne sur le tas sans aucun moyen de le forcer à passer par le garbage collection (ou écrire des 0 à son tampon).

Mon point est : peu importe ce que vous faites, quelque part le long de la ligne, SecureString va être converti en un System.String , ce qui signifie qu'il existera au moins sur le tas à un certain moment (sans aucune garantie de garbage collection).

Mon point n'est pas : existe-t-il des moyens de contourner l'envoi d'une chaîne à une connexion ssh, ou de contourner le fait d'avoir un magasin de contrôle d'une chaîne (faire un contrôle personnalisé). Pour cette question, vous pouvez remplacer «connexion ssh» par «formulaire de connexion», «formulaire d'inscription», «formulaire de paiement», «formulaire de nourritures-vous-nourrissez-votre-chiot-mais-pas-votre-enfant», etc.

  • Alors, à quel moment l'utilisation d'un SecureString devient-elle réellement pratique?
  • Est-ce que cela vaut toujours le temps de développement supplémentaire pour éradiquer complètement l'utilisation d'un objet System.String ?
  • Est-ce que le but de SecureString simplement de réduire le temps que met System.String sur le tas (en réduisant le risque de passer à un fichier d'échange physique)?
  • Si un attaquant a déjà les moyens d'effectuer une inspection de tas, il est probable que (A) a déjà les moyens de lire les frappes, ou (B) possède déjà physiquement la machine ... L'utilisation d'un SecureString empêcherait les données de toute façon?
  • Est-ce juste "sécurité à travers l'obscurité"?

Désolé si je pose des questions trop épais, la curiosité a eu raison de moi. N'hésitez pas à répondre à toutes ou à toutes mes questions (ou dites-moi que mes hypothèses sont complètement fausses). :)




Comme vous l'avez correctement identifié, SecureString offre un avantage spécifique par rapport à la string : l'effacement déterministe. Il y a deux problèmes avec ce fait:

  1. Comme d'autres l'ont mentionné et comme vous l'avez remarqué vous-même, cela ne suffit pas. Vous devez vous assurer que chaque étape du processus (y compris la récupération de l'entrée, la construction de la chaîne, l'utilisation, la suppression, le transport, etc.) se déroule sans pour autant SecureString utilisation de SecureString . Cela signifie que vous devez veiller à ne jamais créer une string immuable gérée par le GC ou tout autre tampon qui stockera les informations sensibles (ou vous devrez également garder une trace de cela ). En pratique, cela n'est pas toujours facile à réaliser, car beaucoup d'API offrent seulement un moyen de travailler avec une string de string , pas avec SecureString . Et même si vous parvenez à tout faire correctement ...
  2. SecureString protège contre des types d'attaques très spécifiques (et pour certains d'entre eux, ce n'est même pas fiable). Par exemple, SecureString vous permet de réduire la fenêtre de temps dans laquelle un attaquant peut vider la mémoire de votre processus et extraire avec succès les informations sensibles (encore une fois, comme vous l'avez souligné), mais espérer que la fenêtre est trop petite pour l'attaquant prendre un instantané de votre mémoire n'est pas du tout considéré comme de la sécurité.

Alors, quand devriez-vous l'utiliser? Seulement lorsque vous travaillez avec quelque chose qui peut vous permettre de travailler avec SecureString pour tous vos besoins et même alors, vous devez toujours être conscient que cela n'est sécurisé que dans des circonstances spécifiques.




Le texte ci-dessous est copié à partir de l'analyseur de code statique HP Fortify

Résumé: La méthode PassString () dans PassGenerator.cs stocke les données sensibles de manière non sécurisée (c'est-à-dire en chaîne), ce qui permet d'extraire les données en inspectant le tas.

Explication: Des données sensibles (telles que des mots de passe, des numéros de sécurité sociale, des numéros de carte de crédit, etc.) stockées en mémoire peuvent être divulguées si elles sont stockées dans un objet String géré. Les objets String ne sont pas épinglés, donc le garbage collector peut déplacer ces objets à volonté et laisser plusieurs copies en mémoire. Ces objets ne sont pas chiffrés par défaut, de sorte que toute personne capable de lire la mémoire du processus pourra voir le contenu. En outre, si la mémoire du processus est transférée sur le disque, le contenu non crypté de la chaîne sera écrit dans un fichier d'échange. Enfin, puisque les objets String sont immuables, la suppression de la valeur d'une chaîne de la mémoire ne peut être effectuée que par le garbage collector du CLR. Le garbage collector n'est pas requis pour s'exécuter à moins que le CLR ne manque de mémoire, il n'y a donc aucune garantie quant au moment où la récupération de place aura lieu. En cas de plantage d'une application, un vidage de la mémoire de l'application peut révéler des données sensibles.

Recommandations: Au lieu de stocker des données sensibles dans des objets tels que les chaînes, stockez-les dans un objet SecureString. Chaque objet stocke son contenu dans un format chiffré en mémoire à tout moment.




Related



Tags

c# c#   security