Toutes les réservations sur unsecuring votre SecureString en créant un System.String sur ce côté , comment peut - il faire?
Comment puis-je convertir un System.Security.SecureString ordinaire en System.String?
Je suis sûr que beaucoup d'entre vous qui connaissent SecureString répondront qu'il ne faut jamais transformer un SecureString en une chaîne .NET ordinaire car cela supprime toutes les protections de sécurité. Je sais . Mais pour le moment, mon programme fait tout avec des chaînes ordinaires de toute façon, et j'essaie d'améliorer sa sécurité et bien que je vais utiliser une API qui me renvoie un SecureString, je n'essaye pas de l'utiliser pour augmenter ma sécurité.
Je connais Marshal.SecureStringToBSTR, mais je ne sais pas comment prendre ce BSTR et en faire un System.String.
Pour ceux qui peuvent demander à savoir pourquoi je voudrais faire cela, eh bien, je prends un mot de passe d'un utilisateur et je le soumets sous forme de formulaire html POST pour connecter l'utilisateur à un site Web. Donc ... cela doit vraiment être fait avec des tampons gérés et non chiffrés. Si je pouvais même accéder au tampon non géré et non chiffré, j'imagine que je pourrais écrire un flux octet par octet sur le flux réseau et espérer que cela maintiendra le mot de passe sécurisé tout au long du trajet. J'espère une réponse à au moins un de ces scénarios.
la source
StopWatch
etSecureStringToString
pris 4,6 secondes pour fonctionner. C'est trop lent pour moi. Quelqu'un at-il le même temps ou quelque chose de plus rapide?Database.GetConnectionString()
dans votre code, pour obtenir mon secureString, qui était la partie perverse qui a pris presque 5sec (et oui je devrais regarder là-dedans! :) Votre code a pris .00 mili secondes dans mon chronomètre donc c'est tout bon. Merci de m'avoir pointé dans la bonne direction.De toute évidence, vous savez comment cela va à l'encontre de l'objectif général d'un SecureString, mais je le répéterai quand même.
Si vous voulez un one-liner, essayez ceci: (.NET 4 et supérieur uniquement)
Où securePassword est un SecureString.
la source
[System.Net.NetworkCredential]::new('', $securePassword).Password
''
pas le même type que[String]::Empty
? AussiNew-Object Net.Credential
ne fonctionne pas pour moi: Vous ne trouvez pas le type [Net.Credential]: vérifier que le contenant assemblage de ce type est chargéDang. juste après avoir publié ceci, j'ai trouvé la réponse au fond de cet article . Mais si quelqu'un sait comment accéder au tampon non géré et non chiffré IntPtr que cette méthode expose, un octet à la fois afin que je n'ai pas à en créer un objet de chaîne gérée pour maintenir ma sécurité élevée, veuillez ajouter une réponse. :)
la source
unsafe
mot - clé et achar*
, il suffit d'appelerbstr.ToPointer()
et de lancer.SecureString.Length
.SecureString
n'essaie pas de masquer la valeur, il essaie d'empêcher que des copies de la valeur soient faites dans des régions qui ne peuvent pas être écrasées de manière fiable, telles que la mémoire récupérée, le fichier d'échange, etc.SecureString
durée de vie se termine, absolument aucune copie du secret ne reste en mémoire. Cela ne vous empêche pas de faire et de divulguer une copie, mais cela ne le fait jamais.À mon avis, les méthodes d'extension sont le moyen le plus confortable de résoudre ce problème.
J'ai pris Steve dans l' excellente réponse de CO et l' ai mise dans une classe d'extension comme suit, avec une deuxième méthode que j'ai ajoutée pour prendre en charge l'autre direction (chaîne -> chaîne sécurisée) également, afin que vous puissiez créer une chaîne sécurisée et la convertir en une chaîne normale après:
Avec cela, vous pouvez maintenant simplement convertir vos chaînes d'avant en arrière comme ceci:
Mais gardez à l'esprit que la méthode de décodage ne doit être utilisée que pour les tests.
la source
Je pense qu'il serait préférable que
SecureString
les fonctions dépendantes encapsulent leur logique dépendante dans une fonction anonyme pour un meilleur contrôle sur la chaîne déchiffrée en mémoire (une fois épinglée).La mise en œuvre pour déchiffrer SecureStrings dans cet extrait de code:
finally
bloc.Cela rend évidemment beaucoup plus facile de «standardiser» et de maintenir les appelants que de compter sur des alternatives moins souhaitables:
string DecryptSecureString(...)
fonction d'assistance.Remarquez ici, vous avez deux options:
static T DecryptSecureString<T>
qui vous permet d'accéder au résultat duFunc
délégué à partir de l'appelant (comme indiqué dans laDecryptSecureStringWithFunc
méthode de test).static void DecryptSecureString
est simplement une version «vide» qui emploie unAction
délégué dans les cas où vous ne voulez / devez rien renvoyer (comme démontré dans laDecryptSecureStringWithAction
méthode de test).Un exemple d'utilisation des deux peut être trouvé dans la
StringsTest
classe incluse.Strings.cs
StringsTest.cs
Évidemment, cela n'empêche pas l'utilisation abusive de cette fonction de la manière suivante, alors faites attention à ne pas le faire:
Bon codage!
la source
Marshal.Copy(new byte[insecureString.Length], 0, insecureStringPointer, (int)insecureString.Length);
place de lafixed
section?[char]
, non[byte]
.String.Empty
, pas l'instance nouvellement allouée créée et renvoyée parMarshal.PtrToStringUni()
.J'ai créé les méthodes d'extension suivantes basées sur la réponse de rdev5 . L'épinglage de la chaîne gérée est important car cela empêche le garbage collector de la déplacer et de laisser des copies que vous ne pouvez pas effacer.
Je pense que l'avantage de ma solution est qu'aucun code dangereux n'est nécessaire.
la source
System.String
objet produiront des copies non épinglées et non effacées. C'est pourquoi cela n'est pas intégréSecureString
.new char[length]
(ou multiplierlength
avecsizeof(char)
).action
délégué ne crée pas de copies de la chaîne temporaire, épinglée, puis remise à zéro, cette approche doit être aussi sûre ou dangereuse qu'elle-SecureString
même - pour utiliser cette dernière, une représentation en texte brut doit également être créé à un moment donné, étant donné que les chaînes sécurisées ne sont pas des constructions au niveau du système d'exploitation; la sécurité relative vient du contrôle de la durée de vie de cette chaîne et de son effacement après utilisation.SecureString
n'a pas de fonctions membres et d'opérateurs surchargés qui font des copies partout.System.String
Est-ce que.NetworkCredential
constructeur qui accepte aSecureString
.Ce code C # est ce que vous voulez.
%ProjectPath%/SecureStringsEasy.cs
la source
J'ai dérivé de cette réponse par sclarke81 . J'aime sa réponse et j'utilise le dérivé mais sclarke81 a un bug. Je n'ai pas de réputation donc je ne peux pas commenter. Le problème semble suffisamment petit pour ne pas justifier une autre réponse et je pourrais le modifier. Alors je l'ai fait. Il a été rejeté. Alors maintenant, nous avons une autre réponse.
sclarke81 J'espère que vous voyez ceci (enfin):
devrait être:
Et la réponse complète avec le correctif de bogue:
la source
La solution de travail finale selon la solution sclarke81 et les correctifs de John Flaherty est:
la source
la source
BSTR
explicitement, et ce n'est pas un objet .NET donc le garbage collector ne s'en charge pas non plus. Comparez à stackoverflow.com/a/818709/103167 qui a été publié 5 ans plus tôt et qui ne fuit pas.Si vous utilisez a
StringBuilder
au lieu de astring
, vous pouvez remplacer la valeur réelle en mémoire lorsque vous avez terminé. De cette façon, le mot de passe ne restera pas en mémoire tant que le garbage collection ne le récupérera pas.la source