Benutzer mit den meisten Antworten
Schützen einer Variable

Frage
-
Ich habe mal wieder eine Frage.
Wie kann ich eine Variable (konkret ein String Objekt und ein byte Array) schützen. D.h. es heißt wie kann ich erreichen, dass diese Variablen nach Benutzung sofort gelöscht werden und wie kann ich verhindern, dass diese Variablen in die Auslagerungsdatei geschrieben werden?
Und kann ich dies in irgendeiner Form nachvollziehen bzw. überprüfen?
Ich hoffe ihr könnt mir in diesen Punkte weiterhelfen und vielen Dank schon einmal in vor raus.
Antworten
-
Hallo Simon,
Die Stärke und Schwäche von SecureString ist, dass es die Methoden SystemFunction040 (d.h. CryptProtectMemory [DPAPI/Crypt32.dll], auf Vor-Vista Systemen RtlEncryptMemory [Advapi32.dll]) und SystemFunction041 (d.h. CryptUnprotectMemory bzw. RtlDecryptMemory) bei jeder Erweiterung des gespeicherten Inhalts zur Laufzeit verwendet. Diese Funktionen werden in der mscorlib mit dem Option-Flag 0 aufgerufen, was die Verschlüsselung außerhalb des laufenden Prozesses bis auf weiteres unmöglich macht. Landet der Speicherinhalt in die Auslagerungsdatei (wüßte nicht gleich wie, da nicht-verwalteter und nicht auslagerbarer Speicher verwendet wird) würde das keinen realen Wert für den Angreifer haben, da außerhalb des Prozesses nicht entschlüsselbar. Crasht der Rechner während der Verschlüsselung jedoch, dann könnte der Klartext den man gerade verschlüsselt u.U. in einer Speicherabbilddatei (dump) landen, was ich eher für ein reales und ernstzunehmendes Risiko-Szenario halte. Zusammengefaßt: Die Verwendung von verwalteten Byte-Arrays für die Speicherung von sehr sensitiven Informationen kann man sich abschminken. Das sicherste, was z.Z. verfügbar ist, ist SecureString. Es gibt Tools, die zwar in den Prozessraum der Anwendung injiziert werden können und so jeden SecureString zur Laufzeit auslesen können, aber außerhalb des Prozesses ist der Inhalt eines verschlüsselten SecureStrings wertlos. Verwende ein modernes Windows-Betriebsystem mit dem letzten .NET-Framework und Du bist so sicher, wie man z.Z. sein kann.
Gruß
Marcel- Als Antwort markiert Simon Rühle Freitag, 12. April 2013 11:54
Alle Antworten
-
Hallo, ich nehme mal an das du die Variablen gegen das lesen im Arbeitsspeicher schützen möchtest. Schau dir mal folgende Klasse an:
http://msdn.microsoft.com/de-de/library/system.security.securestring.aspxVerhindern das eine Variable in der Auslagerungsdatei landet kann man nicht, da dieser wie RAM behandelt wird. Mit der GC-Klasse kann man etwas einfluss darauf nehmen wann eine Variable gelöscht werden soll.
<Code:13/> - Koopakiller [kuːpakɪllɐ]
Webseite | Code Beispiele | Facebook | Snippets
Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.
Einen Konverter zwischen C# und VB.NET Code gibt es hier. -
Nun ja, da es in an einer Kryptographie Anwendung arbeite, sollte der Key nicht in der Auslagerungsdatei landen. Gibt es zumindest eine Möglichkeit dies Festzustellen und die Variable anschließend zu überschreiben. Oder gibt es eine Möglichkeit zu Erzwingen, dass die Variable wenn sie einmal gesetzt wurde, immer im gleichen Speicherbereich liegt, dann könnte ich sie nämlich einfach mehrfach überschreiben.
- Als Antwort vorgeschlagen Elmar BoyeEditor Sonntag, 7. April 2013 14:56
- Nicht als Antwort vorgeschlagen Elmar BoyeEditor Sonntag, 7. April 2013 14:56
-
Hi Simon,
ich weiß jetzt nicht genau was du machen möchtest. Aber für Kryptographie Anwendungen hat das Frameworke eigene Klassen.
MFG
Björn
-
Hallo Simon,
vorab: Ich bin kein Sicherheitsexperte (wie die wohl meisten hier); die könnten dazu mehr sagen. (Trotzdem) einige Überlegungen meinerseits:
Ein "gleicher Speicherbereich" ist nicht von Vorteil, da er es einem Angreifer leichter macht, einen kritischen Bereich zu ermitteln. Und der Speicher eines Prozesses lässt sich - ggf. auf Umwegen wie Dll Injection - auslesen.
Eine Ablage im Nonpaged Pool Memory vermeidet zwar die Ablage in der Auslagerungsdatei macht es aber umgekehrt leichter, da der Adressbereich deutlich kleiner ist. Mehr zu den Möglichkeiten der Speicherallokierung siehe VirtualAlloc[Ex].
Ein ungeschützter Wert sollte nur so kurz wie möglich existieren. Den Weg beschreitet das bereits erwähnte SecureString, in dem es den Wert verschlüsselt speichert (RtlEncryptMemory) und für den Zugriff entschlüsselt (RtlDecryptMemory).
Die "unhandlichen" Zugriffsmethoden sind dabei Absicht. Denn nur so vermeidet man, dass Zeichenketten im Speicher verbleiben (vorausgesetzt die Klasse wird richtig eingesetzt). Ebenso muss man sich im klaren sein, dass durch die Verschlüsselung der Zugriff nicht schnellste ist - was aber für kleinere Mengen kein Problem darstellen sollte. Eine Möglichkeit wäre evtl. die ProtectedData Class - wenn man nicht gleich unmanaged anfangen will.
Gruß Elmar
-
Hallo Simon,
sollte Dir die Antworten geholfen haben, markiere sie bitte als Antwort.
Grüße,
Stefan Kleinewillinghoefer, MICROSOFT
Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwicklern“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden koennen.
-
Die SecureString Klasse wurde schon mehrfach angesprochen. Wie verschlüsselt diese den gespeicherten String? Die Dokumentation ist da mit Informationen zu diesem Aspekt etwas zurückhaltend. Eine weitere Frage ist, ob SecureString sich vor dem Schreiben in die Auslagerungsdatei schützt?
-
Hallo Simon,
das Verhalten hatte ich in meiner Antwort angedeutet:
Die Daten werden intern bei jedem Zugriff entschlüsselt, die Operation ausgeführt und sofort wieder verschlüsselt.
AppendChar sieht gekürzt so aus:
this.UnProtectMemory(); this.m_buffer.Write<char>((ulong)(this.m_length * 2), c); this.m_length++; this.ProtectMemory()
wobei <Un>ProtectMemory die oben verlinkten API-Methoden verwenden. m_buffer basiert auf der SafeBuffer Klasse.
Entsprechend gehen die anderen Methoden vor.
Gruß Elmar
- Bearbeitet Elmar BoyeEditor Dienstag, 9. April 2013 16:59
-
Hallo Simon,
Eine weitere Frage ist, ob SecureString sich vor dem Schreiben in die Auslagerungsdatei schützt?
SecureString ist zu keinem Zeitpunkt unverschlüsselt im Speicher. Deswegen würde ich mir keine Sorgen wegen der Auslagerung machen. Allerdings ist ein eventueller vor- bzw. nachgeschalteter Klartext, so dieser nicht über die SecureString-Methoden hinzugefügt wird, eine leichte Beute. Der beste Schutz besteht - wie auch in anderen Sachen - "es nicht zu tun", d.h. man darf den Schlüssel einfach nie aus der Hand geben. Das geht z.B. indem Du den Schlüssel und die ganze Verschlüsselung hinter einem WCF-Dienst verbirgst. Alles andere Methoden, inklusive DPAPI-Verschlüsselung leiden darunter, dass ein Angreifer mit administrativem Zugriff auf das System nur noch das einschlägige Wissen und einen guten Debugger braucht. Aber wer Zugriff auf das System hat, der braucht die kryptografische Schicht gar nicht zu durchbrechen! Er kann sich ja ganz bequem über einen Wrapper zwischen Aufrufer und der kryptografischen Schicht schalten, warum sollte er sich all die Mühe machen. Sicherheit muss man sich immer wie eine Kette vorstellen, die so schwach wie das schwächste Glied ist. Glaub mir bitte, es macht gar keinen Sinn sich solche Fragen zu stellen, wie Du das hier tust, wenn man davon ausgeht, dass der Angreifer Zugriff auf die Auslagerungsdatei hat. Dann ist alles verloren.
Gruß
Marcel -
Hallo Marcel,
es geht mir nicht darum einen Angriff zur Laufzeit abzuwehren, da dies, wie du korrekt ausgeführt hast nicht möglich ist, wenn man z.B. einen Trojaner auf dem System hat.
Der Punkt ist vielmehr, dass wenn die Verschlüsselung erfolgt ist, und jemand Zugriff auf die Festplatte hat, keine Möglichkeit besteht an den Key mehr heranzukommen, wie es ja bei einer Auslagerung in die Auslagerungsdatei der Fall ist.
D.h. ich muss dafür sorgen, dass der Key nur während bzw. auch kurz vor der Verschlüsselung vorhanden und somit angreifbar ist.
Die Frage die ich bezüglich der Verschlüsselung des SecureString Objekt hatte, ist die, wenn dieses Objekt in der Auslagerungsdatei landet, ist es nach Abschluss der Benutzung, noch möglich diesen SecureString zu entschlüsseln? Und wie wird es überhaupt verschlüsselt (was wird als Key genommen und welches Verschlüsselungsverfahren wird genutzt)?
-
Hallo Simon,
wenn ich das richtig sehe, wird in die Auslagerungsdatei auch nur das geschrieben, was im Hauptspeicher liegen würde. Da der SecureString immer nur für einen minimalen Zeitraum entschlüsselt vorliegt, dürfte das Risiko gering sein, dass er unverschlüsselt dort landet. Eine 100%ige Sicherheit gibt es allerdings weder hier noch sonstwo.
Um deine weiteren Fragen beantworten zu können, muss man den Code der entsprechenden Klasse detailliert analysieren, eine Doku hierzu gibt es AFAICS nicht. Daher würde ich dir empfehlen, mit einem Decompiler wie bspw. JustDecompile, .NET Reflector, ... in den Code zu schauen. Damit solltest Du deine Fragen evtl. beantworten können. (Allerdings ist das IMHO keine leichte Kost, wenn man da komplett durchsteigen will :)
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Hallo Simon,
Die Stärke und Schwäche von SecureString ist, dass es die Methoden SystemFunction040 (d.h. CryptProtectMemory [DPAPI/Crypt32.dll], auf Vor-Vista Systemen RtlEncryptMemory [Advapi32.dll]) und SystemFunction041 (d.h. CryptUnprotectMemory bzw. RtlDecryptMemory) bei jeder Erweiterung des gespeicherten Inhalts zur Laufzeit verwendet. Diese Funktionen werden in der mscorlib mit dem Option-Flag 0 aufgerufen, was die Verschlüsselung außerhalb des laufenden Prozesses bis auf weiteres unmöglich macht. Landet der Speicherinhalt in die Auslagerungsdatei (wüßte nicht gleich wie, da nicht-verwalteter und nicht auslagerbarer Speicher verwendet wird) würde das keinen realen Wert für den Angreifer haben, da außerhalb des Prozesses nicht entschlüsselbar. Crasht der Rechner während der Verschlüsselung jedoch, dann könnte der Klartext den man gerade verschlüsselt u.U. in einer Speicherabbilddatei (dump) landen, was ich eher für ein reales und ernstzunehmendes Risiko-Szenario halte. Zusammengefaßt: Die Verwendung von verwalteten Byte-Arrays für die Speicherung von sehr sensitiven Informationen kann man sich abschminken. Das sicherste, was z.Z. verfügbar ist, ist SecureString. Es gibt Tools, die zwar in den Prozessraum der Anwendung injiziert werden können und so jeden SecureString zur Laufzeit auslesen können, aber außerhalb des Prozesses ist der Inhalt eines verschlüsselten SecureStrings wertlos. Verwende ein modernes Windows-Betriebsystem mit dem letzten .NET-Framework und Du bist so sicher, wie man z.Z. sein kann.
Gruß
Marcel- Als Antwort markiert Simon Rühle Freitag, 12. April 2013 11:54