Frage

Ich versuche, den Zweck von SecureString von .NET zu verstehen.Von MSDN:

Eine Instanz der System.String-Klasse ist unveränderlich und kann, wenn sie nicht mehr benötigt wird, nicht programmgesteuert für die Speicherbereinigung eingeplant werden.Das heißt, die Instanz ist nach ihrer Erstellung schreibgeschützt und es ist nicht möglich vorherzusagen, wann die Instanz aus dem Computerspeicher gelöscht wird.Wenn ein String-Objekt vertrauliche Informationen wie ein Passwort, eine Kreditkartennummer oder persönliche Daten enthält, besteht daher das Risiko, dass die Informationen nach der Verwendung preisgegeben werden, da Ihre Anwendung die Daten nicht aus dem Computerspeicher löschen kann.

Ein SecureString-Objekt ähnelt einem String-Objekt darin, dass es einen Textwert hat.Der Wert eines SecureString-Objekts wird jedoch automatisch verschlüsselt, kann geändert werden, bis Ihre Anwendung es als schreibgeschützt markiert, und kann entweder von Ihrer Anwendung oder dem .NET Framework-Garbage Collector aus dem Computerspeicher gelöscht werden.

Der Wert einer Instanz von SecureString wird automatisch verschlüsselt, wenn die Instanz initialisiert oder der Wert geändert wird.Ihre Anwendung kann die Instanz unveränderlich machen und weitere Änderungen verhindern, indem sie die MakeReadOnly-Methode aufruft.

Ist die automatische Verschlüsselung der große Gewinn?

Und warum kann ich nicht einfach sagen:

SecureString password = new SecureString("password");

anstatt

SecureString pass = new SecureString();
foreach (char c in "password".ToCharArray())
    pass.AppendChar(c);

Welcher Aspekt von SecureString fehlt mir?

War es hilfreich?

Lösung

Einige Teile des Frameworks, die derzeit verwendet werden SecureString:

Der Hauptzweck besteht darin, die Angriffsfläche zu verringern, anstatt sie zu beseitigen. SecureStrings werden im RAM „gepinnt“, sodass der Garbage Collector sie nicht verschiebt oder Kopien davon anfertigt.Es stellt außerdem sicher, dass der Klartext nicht in die Swap-Datei oder in Core-Dumps geschrieben wird.Die Verschlüsselung ähnelt eher einer Verschleierung und wird einen entschlossenen Hacker, der das finden könnte, jedoch nicht aufhalten symmetrischer Schlüssel verwendet, um es zu verschlüsseln und zu entschlüsseln.

Wie andere bereits gesagt haben, ist der Grund, warum Sie eine erstellen müssen SecureString Zeichen für Zeichen ist auf den ersten offensichtlichen Fehler zurückzuführen, der darin besteht, etwas anderes zu tun:Vermutlich haben Sie den geheimen Wert bereits als einfache Zeichenfolge. Was ist also der Sinn?

SecureStrings sind der erste Schritt zur Lösung eines Henne-Ei-Problems. Auch wenn die meisten aktuellen Szenarien eine Rückumwandlung in reguläre Strings erfordern, um sie überhaupt nutzen zu können, bedeutet ihre Existenz im Framework jetzt eine bessere Unterstützung für sie im Zukunft - zumindest bis zu einem Punkt, an dem Ihr Programm nicht das schwache Glied sein muss.

Andere Tipps

Es gibt viele gute Antworten; hier eine kurze Zusammenfassung dessen, was besprochen wurde.

Microsoft hat die Secure Klasse in dem Bemühen, implementiert eine bessere Sicherheit mit sensiblen Informationen (wie Kreditkarten, Passwörter, etc.). Es automatisch bestimmt:

  • Verschlüsselung (im Falle von Speicherabbilder oder Seiten-Caching)
  • im Speicher Pinning
  • Fähigkeit als schreibgeschützt zu markieren (zu verhindern, dass weitere Modifikationen)
  • sichere Konstruktion durch keine konstante String ermöglicht in weitergegeben werden

Derzeit ist Secure im Einsatz beschränkt, sondern eine bessere Annahme in der Zukunft erwarten.

Auf der Grundlage dieser Informationen sollte der Konstruktor des Secure nicht nur eine Zeichenfolge nehmen und in Scheiben schneidet Array auf char als die Zeichenfolge mit Dinkel Niederlagen den Zweck von Secure.

Weitere Informationen:

  • Post von .NET Sicherheit Blog reden über viel das gleiche wie hier abgedeckt.
  • Und noch ein ein Neubetrachtung es und ein Werkzeug zu erwähnen, Das kann den Inhalt der Dump Secure.

Edit: Ich fand es schwer, die beste Antwort zu holen, da es in vielen guten Informationen ist; schade gibt es keine unterstützten Antwortmöglichkeiten.

Kurze Antwort

  

Warum kann ich nicht einfach sagen:

SecureString password = new SecureString("password");

Da Sie nun im Speicher password haben; ohne die Möglichkeit, es zu wischen -. das ist genau der Punkt, der ist Secure

Lange Antwort

Der Grund Secure existiert, ist, weil Sie nicht verwenden können Zeromemory sensible Daten wischen, wenn Sie mit ihm fertig sind. Es besteht ein Problem zu lösen, die weil der CLR existiert.

In einer regulären nativer Anwendung würden Sie nennen? SecureZeroMemory :

  

Füllt einen Block des Speichers mit Nullen.

Hinweis : SecureZeroMemory ist identisch mit ZeroMemory außer den Compiler wird es nicht weg optimieren.

Das Problem ist, dass Sie auf kann nicht Anruf ZeroMemory oder SecureZeroMemory innerhalb .NET. Und in .NET-Strings sind unveränderlich; Sie können nicht einmal Überschreiben den Inhalt der Zeichenfolge wie Sie in anderen Sprachen tun können:

//Wipe out the password
for (int i=0; i<password.Length; i++)
   password[i] = \0;

Also, was können Sie tun? Wie schaffen wir die Möglichkeit, in .NET ein Passwort oder Kreditkartennummer aus dem Gedächtnis zu tilgen, wenn wir damit fertig sind?

Der einzige Weg, es kann getan werden, wäre die Zeichenfolge zu platzieren in einigen nativer Speicherblock, in dem Sie auf können dann ZeroMemory nennen. Ein native Speicherobjekt wie zum Beispiel:

  • ein BSTR
  • ein HGLOBAL
  • CoTaskMem nicht verwalteten Speicher

Secure gibt die verlorene Fähigkeit zurück

In .NET Strings können nicht ausgelöscht werden, wenn Sie mit ihnen fertig sind:

  • Sie sind unveränderlich; Sie können uns ihre Inhalte nicht
  • überschreiben
  • Sie können nicht Dispose von ihnen
  • ihre Bereinigung ist auf Gedeih und Verderb der Garbage Collector

Secure existiert als eine Möglichkeit, um die Sicherheit Saiten passieren, und in der Lage, ihre Bereinigung zu garantieren, wenn Sie müssen.

Sie stellte die Frage:

  

Warum kann ich nicht einfach sagen:

SecureString password = new SecureString("password");

Da Sie nun im Speicher password haben; ohne die Möglichkeit, es zu wischen. Es ist dort stecken, bis die CLR, dass der Speicher wieder verwenden, um zu entscheiden geschieht. Sie haben uns gleich wieder, wo wir angefangen; eine laufende Anwendung mit einem Passwort können wir nicht loswerden, und wo ein Speicherabbild (oder Process Monitor), um das Passwort sehen.

Secure verwendet die Data Protection API die Zeichenfolge im Speicher verschlüsselt zu speichern; auf diese Weise wird der String nicht in swapfiles existiert, Crash-Dumps, oder auch in den lokalen Variablen-Fenstern mit einem Kollegen sucht über Ihr soll.

Wie lese ich das Passwort?

Dann ist die Frage: Wie kann ich mit dem String interagieren? Sie absolut nicht wollen ein Verfahren wie:

String connectionString = secureConnectionString.ToString()

denn jetzt bist du wieder da, wo Sie begonnen haben - ein Passwort können Sie nicht loswerden. Sie möchten Kraft Entwickler die empfindliche Saite richtig zu handhaben - so dass es können aus dem Gedächtnis gewischt werden.

Deshalb .NET bietet drei handliche Helfer Funktionen marshall einen Secure in einen nicht verwalteten Speicher:

Sie konvertieren den String in einen nicht verwalteten Speicher Klecks, damit umgehen, und es dann wieder abzuwischen.

Einige APIs akzeptieren SecureStrings . Zum Beispiel in ADO.net 4.5 der SqlConnection.Credential nimmt ein Satz SqlCredential :

SqlCredential cred = new SqlCredential(userid, password); //password is SecureString
SqlConnection conn = new SqlConnection(connectionString);
conn.Credential = cred;
conn.Open();

Sie können auch das Passwort innerhalb einer Connection String ändern:

SqlConnection.ChangePassword(connectionString, cred, newPassword);

Und es gibt eine Menge von Orten innerhalb .NET, wo sie weiterhin eine einfache String aus Kompatibilitätsgründen akzeptieren, dann schnell einen Put umdrehen es in einen Secure.

Wie Text in das Secure setzen?

Damit bleibt immer noch das Problem:

  

Wie bekomme ich ein Passwort in das Secure in erster Linie?

Das ist die Herausforderung, aber der Punkt ist, um Sie über die Sicherheit zu bekommen denken.

Manchmal ist die Funktionalität bereits für Sie bereitgestellt. Zum Beispiel ist die WPF PasswordBox Kontrolle zurückgeben können Sie das eingegebene Passwort als ein Secure direkt:

  

PasswordBox .SecurePassword Property

     

Ruft das Kennwort derzeit von der PasswordBox als Secure .

Dieses hilfreich ist, weil überall verwendet, um Sie um einen rohen String zu übergeben, haben Sie jetzt die Art System beschweren, dass Secure unvereinbar mit String ist. Sie wollen so lange wie möglich gehen, bevor Ihr Secure zurück in reguläre Zeichenfolge konvertieren zu müssen.

ein Secure Konvertieren ist einfach genug:

  • SecureStringToBSTR
  • PtrToStringBSTR

, wie in:

private static string CreateString(SecureString secureString)
{
    IntPtr intPtr = IntPtr.Zero;
    if (secureString == null || secureString.Length == 0)
    {
        return string.Empty;
    }
    string result;
    try
    {
        intPtr = Marshal.SecureStringToBSTR(secureString);
        result = Marshal.PtrToStringBSTR(intPtr);
    }
    finally
    {
        if (intPtr != IntPtr.Zero)
        {
            Marshal.ZeroFreeBSTR(intPtr);
        }
    }
    return result;
}

Sie nur wirklich wollen Sie nicht, es zu tun.

Aber wie bekomme ich eine Zeichenfolge in einen Secure? Nun, was Sie tun müssen, um ein Passwort zu stoppen, die in einem String in dem ersten Platz. Sie müssen es hat in etwas sonst. Selbst ein Char[] Array hilfreich sein würde.

Das ist, wenn Sie jedes Zeichen anhängen und wischen den Klartext, wenn Sie fertig sind:

for (int i=0; i < PasswordArray.Length; i++)
{
   password.AppendChar(PasswordArray[i]);
   PasswordArray[i] = (Char)0;
}

Sie müssen Ihr Passwort gespeichert in einige Erinnerung, die Sie wischen können. Legen Sie es in den Secure von dort aus.


tl; dr: Secure existiert das Äquivalent von zu schaffen Zeromemory

.

Einige Leute sehen nicht den Punkt in das Kennwort des Benutzers Abwischen aus dem Speicher, wenn ein Gerät wird verriegelt oder nach they'authenticated Tastenanschläge aus dem Speicher abwischt. Diese Menschen nicht Secure verwenden.

Es gibt nur sehr wenige Situationen, in denen man vernünftig Secure in der aktuellen Version des Framework verwenden kann. Es ist eigentlich nur für mit nicht verwalteten APIs interagieren - Sie können es mit Marshal.SecureStringToGlobalAllocUnicode Marschall kann.

Sobald Sie es zu / von einem System.String konvertieren, Sie seinen Zweck besiegt haben.

Die MSDN Probe erzeugt die Secure ein Zeichen zu einer Zeit aus Konsoleneingabe und übergibt die sichere Zeichenfolge an eine nicht verwaltete API. Es ist ziemlich verworren und unrealistisch.

könnten Sie erwarten, dass zukünftige Versionen von .NET für Secure mehr Unterstützung haben, die es nützlicher machen, z.

  • Secure Console.ReadLineSecure () oder ähnliche Konsoleneingabe in eine Secure ohne all den gewundenen Code in der Probe.

  • lesen
  • WinForms TextBox-Ersatz, der seine TextBox.Text Eigenschaft als sichere Zeichenfolge speichert, so dass Passwörter sicher eingegeben werden können.

  • Erweiterungen zu sicherheitsrelevanten APIs Passwörter zu ermöglichen, übergeben, wie Secure werden.

Ohne die oben Gesagte Secure von begrenztem Wert sein.

Ich glaube, den Grund, warum Sie Charakter zu tun haben, statt einer flachen Instanziierung anhängt, weil im Hintergrund „Passwort“ an den Konstruktor von Secure vorbei bringt, dass „Passwort“ string im Speicher den Zweck des sicheren Zeichenfolge zu besiegen.

Durch das Anhängen Sie sind nur ein Zeichen in einer Zeit in dem Speicher setzen, die nicht benachbart zueinander physisch macht es viel schwieriger likley ist die ursprüngliche Zeichenfolge zu rekonstruieren. Ich könnte falsch sein, hier aber das ist, wie es wurde mir erklärt.

Der Zweck der Klasse ist ein sicheren Daten zu verhindern, dass über ein Speicherabbild oder ein ähnliches Werkzeug ausgesetzt.

gefunden MS, dass auf bestimmte Fälle, dass der Server (Desktop, was auch immer) zum Absturz gab es Zeiten, wenn die Laufzeitumgebung ein Speicherabbild tun würde, um den Inhalt des Aussetzen, was im Speicher ist. Sichere String verschlüsselt im Speicher, den Angreifer zu verhindern, dass in der Lage, den Inhalt der Zeichenfolge abzurufen.

Einer der großen Vorteile eines Secure ist, dass es soll die Möglichkeit, Ihre Daten vermeiden aufgrund Seiten-Caching auf der Festplatte gespeichert werden. Wenn Sie ein Passwort im Speicher haben und dann ein großes Programm oder Datensatz laden, Ihr Passwort in die Auslagerungsdatei erhält geschrieben als Ihr Programm aus dem Speicher ausgelagert wird. Mit Secure, zumindest werden die Daten nicht sitzen um auf unbestimmte Zeit auf Ihrer Festplatte in Klartext.

Ich denke, es ist, weil die Saite sicher sein soll, das heißt ein Hacker sollte es nicht in der Lage sein zu lesen. Wenn Sie es mit einem String initialisieren, könnte der Hacker die ursprüngliche Zeichenfolge lesen.

Nun, da die Beschreibung heißt es, wird der Wert verschlüsselt gespeichert, mit Mitteln, dass ein Speicherabbild des Prozesses wird die Zeichenfolge des Wert nicht verraten (ohne einig ziemlich ernsthafte Arbeit).

Der Grund, Sie können nicht nur eine Secure von einem konstanten String konstruieren ist, weil dann Sie würde haben eine unverschlüsselte Version der Zeichenfolge im Speicher. Die Begrenzung Sie die Zeichenfolge in Stücke zu schaffen reduziert das Risiko von auf einmal die gesamte Zeichenfolge in Speicher.

Ich würde aufhören Secure verwenden. Sieht aus wie PG Jungs Unterstützung fallen für sie. Möglicherweise sogar ziehen sie in die Zukunft - https://github.com / dotnet / apireviews / Baum / Master / 2015.07.14-secure .

  

Wir sollten entfernen Sie die Verschlüsselung Secure über alle Plattformen hinweg in .NET Kern - Wir sollten veraltete Secure - Wir sollten wahrscheinlich nicht Secure in .NET-Core aussetzen

Ein weiterer Anwendungsfall ist, wenn Sie mit Zahlungsanwendungen arbeiten (PO) und Sie einfach können unveränderlich Datenstrukturen nicht verwenden , um sensible Daten zu speichern, weil Sie vorsichtig Entwickler sind. Zum Beispiel: Wenn ich dort sensible Kartendaten oder Berechtigungs Metadaten in unveränderliche Zeichenfolge gespeichert werde immer dann der Fall, wenn diese Daten im Speicher für erhebliche Menge an Zeit zur Verfügung stehen, nachdem es wurde verworfen. Ich kann es nicht einfach überschreiben. Ein weiterer großer Vorteil, wenn diese sensiblen Daten verschlüsselt im Speicher gehalten wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top