Alle Reservierungen über Entsichern Ihre Secure durch einen System.String aus ihm zu schaffen beiseite , wie es getan werden kann?
Wie kann ich einen normalen System.Security.SecureString in System.String konvertieren?
Ich bin sicher, dass viele von Ihnen, die mit SecureString vertraut sind, antworten werden, dass man einen SecureString niemals in eine normale .NET-Zeichenfolge umwandeln sollte, da dadurch alle Sicherheitsmaßnahmen aufgehoben werden. Ich weiß . Aber im Moment macht mein Programm sowieso alles mit gewöhnlichen Zeichenfolgen, und ich versuche, seine Sicherheit zu verbessern, und obwohl ich eine API verwenden werde, die mir einen SecureString zurückgibt, versuche ich nicht , diese zu verwenden, um meine Sicherheit zu erhöhen.
Ich kenne Marshal.SecureStringToBSTR, aber ich weiß nicht, wie ich diesen BSTR nehmen und daraus einen System.String machen soll.
Für diejenigen, die wissen möchten, warum ich dies jemals tun möchte, nehme ich ein Passwort von einem Benutzer und sende es als HTML-Formular POST, um den Benutzer auf einer Website anzumelden. Also ... das muss wirklich mit verwalteten, unverschlüsselten Puffern gemacht werden. Wenn ich überhaupt Zugriff auf den nicht verwalteten, unverschlüsselten Puffer erhalten könnte, könnte ich mir vorstellen, dass ich Byte-für-Byte-Streams in den Netzwerk-Stream schreiben könnte, und hoffe, dass das Passwort dadurch auf dem gesamten Weg sicher bleibt. Ich hoffe auf eine Antwort auf mindestens eines dieser Szenarien.
quelle
StopWatch
undSecureStringToString
gebraucht, um zu laufen. Es ist zu langsam für mich. Bekommt jemand die gleiche Zeit oder etwas schneller?Database.GetConnectionString()
in Ihren Code eingefügt, um meinen SecureString zu erhalten, was der böse Teil war, der fast 5 Sekunden dauerte (und ja, ich sollte das untersuchen! :) Ihr Code hat in meiner Stoppuhr 0,00 Mili Sekunden gedauert, also ist es alles gut. Danke, dass du mich in die richtige Richtung gelenkt hast.Natürlich wissen Sie, wie dies den gesamten Zweck eines SecureString zunichte macht, aber ich werde es trotzdem wiederholen.
Wenn Sie einen Einzeiler möchten, versuchen Sie Folgendes: (Nur .NET 4 und höher)
Wobei SecurePassword ein SecureString ist.
quelle
[System.Net.NetworkCredential]::new('', $securePassword).Password
''
nicht der gleiche Typ wie[String]::Empty
? Funktioniert auchNew-Object Net.Credential
nicht für mich: Typ [Net.Credential] kann nicht gefunden werden: Überprüfen Sie, ob die Assembly mit diesem Typ geladen istDang. Gleich nach dem Posten fand ich die Antwort tief in diesem Artikel . Wenn jedoch jemand weiß, wie er auf den nicht verwalteten, unverschlüsselten IntPtr-Puffer zugreifen kann, den diese Methode byteweise verfügbar macht, damit ich kein verwaltetes Zeichenfolgenobjekt daraus erstellen muss, um meine Sicherheit hoch zu halten, fügen Sie bitte eine Antwort hinzu. :) :)
quelle
unsafe
Schlüsselwort und a verwendenchar*
, einfach anrufenbstr.ToPointer()
und umsetzen.SecureString.Length
.SecureString
versucht nicht, den Wert auszublenden, sondern zu verhindern, dass Kopien des Werts in Regionen erstellt werden, die nicht zuverlässig überschrieben werden können, z. B. Speicherplatz, Auslagerungsdatei usw. Die Absicht ist, dass dieSecureString
Lebensdauer absolut endet, wenn sie endet Es bleibt keine Kopie des Geheimnisses im Speicher. Es hindert Sie nicht daran, eine Kopie zu erstellen und zu verlieren, aber es tut es nie.Meiner Meinung nach sind Erweiterungsmethoden der bequemste Weg, dies zu lösen.
Ich habe Steve in die ausgezeichnete Antwort von CO aufgenommen und sie wie folgt in eine Erweiterungsklasse eingeordnet, zusammen mit einer zweiten Methode, die ich hinzugefügt habe, um auch die andere Richtung (Zeichenfolge -> sichere Zeichenfolge) zu unterstützen, sodass Sie eine sichere Zeichenfolge erstellen und in diese konvertieren können eine normale Zeichenfolge danach:
Damit können Sie Ihre Saiten jetzt einfach so hin und her konvertieren :
Beachten Sie jedoch, dass die Dekodierungsmethode nur zum Testen verwendet werden sollte.
quelle
Ich denke, es wäre am besten, wenn
SecureString
abhängige Funktionen kapseln würden ihre abhängige Logik in einer anonymen Funktion um die entschlüsselte Zeichenfolge im Speicher (einmal fixiert) besser kontrollieren zu können.Die Implementierung zum Entschlüsseln von SecureStrings in diesem Snippet wird:
finally
Block los.Dies macht es offensichtlich viel einfacher, Anrufer zu "standardisieren" und zu warten, als sich auf weniger wünschenswerte Alternativen zu verlassen:
string DecryptSecureString(...)
Hilfsfunktion.Beachten Sie, dass Sie hier zwei Möglichkeiten haben:
static T DecryptSecureString<T>
Hiermit können SieFunc
vom Aufrufer aus auf das Ergebnis des Delegaten zugreifen (wie in derDecryptSecureStringWithFunc
Testmethode gezeigt ).static void DecryptSecureString
ist einfach eine "void" -Version, die einenAction
Delegaten in Fällen beschäftigt, in denen Sie tatsächlich nichts zurückgeben möchten / müssen (wie in derDecryptSecureStringWithAction
Testmethode gezeigt).Eine Beispielverwendung für beide finden Sie in der enthaltenen
StringsTest
Klasse.Strings.cs
StringsTest.cs
Dies verhindert natürlich nicht den Missbrauch dieser Funktion auf folgende Weise. Achten Sie also darauf, dies nicht zu tun:
Viel Spaß beim Codieren!
quelle
Marshal.Copy(new byte[insecureString.Length], 0, insecureStringPointer, (int)insecureString.Length);
anstelle desfixed
Abschnitts verwenden?[char]
, nicht[byte]
.String.Empty
haben. nicht die neu zugewiesene Instanz, die von erstellt und zurückgegeben wurdeMarshal.PtrToStringUni()
.Ich habe die folgenden Erweiterungsmethoden basierend auf der Antwort von rdev5 erstellt . Das Fixieren der verwalteten Zeichenfolge ist wichtig, da dadurch verhindert wird, dass der Garbage Collector sie verschiebt und Kopien zurücklässt, die Sie nicht löschen können.
Ich denke, der Vorteil meiner Lösung ist, dass kein unsicherer Code benötigt wird.
quelle
System.String
Objekt erstellt nicht fixierte und nicht gelöschte Kopien. Deshalb ist das nicht eingebautSecureString
.new char[length]
(oder mehrfachlength
mitsizeof(char)
).action
Delegat keine Kopien der temporären, angehefteten und dann auf Null gesetzten Zeichenfolge erstellt, sollte dieser Ansatz so sicher oder unsicher sein wie erSecureString
selbst - um Letzteres zu verwenden, muss auch eine Klartextdarstellung verwendet werden irgendwann erstellt werden, da sichere Zeichenfolgen keine Konstrukte auf Betriebssystemebene sind; Die relative Sicherheit besteht darin, die Lebensdauer dieser Zeichenfolge zu kontrollieren und sicherzustellen, dass sie nach der Verwendung gelöscht wird.SecureString
hat keine Mitgliedsfunktionen und überladene Operatoren, die überall Kopien erstellen .System.String
tut.NetworkCredential
Konstruktor weitergegeben wird, der a akzeptiertSecureString
.Dieser C # -Code ist genau das, was Sie wollen.
%ProjectPath%/SecureStringsEasy.cs
quelle
Ich habe aus dieser Antwort von sclarke81 abgeleitet . Ich mag seine Antwort und ich benutze das Derivat, aber sclarke81 hat einen Fehler. Ich habe keinen Ruf, kann also keinen Kommentar abgeben. Das Problem scheint klein genug zu sein, dass es keine weitere Antwort rechtfertigte und ich es bearbeiten konnte. So tat ich. Es wurde abgelehnt. Jetzt haben wir also eine andere Antwort.
sclarke81 Ich hoffe du siehst das (endlich):
sollte sein:
Und die vollständige Antwort mit der Fehlerbehebung:
quelle
Die endgültige Arbeitslösung gemäß der Lösung von sclarke81 und den Korrekturen von John Flaherty lautet:
quelle
quelle
BSTR
explizit frei und es ist kein .NET-Objekt, also kümmert sich der Garbage Collector auch nicht darum. Vergleiche mit stackoverflow.com/a/818709/103167, das 5 Jahre zuvor veröffentlicht wurde und nicht leckt .Wenn Sie a
StringBuilder
anstelle von a verwendenstring
, können Sie den tatsächlichen Wert im Speicher überschreiben, wenn Sie fertig sind. Auf diese Weise bleibt das Kennwort erst im Speicher hängen, wenn die Speicherbereinigung es aufnimmt.quelle