Korrektes, verschlüsseltes Aufbewahren von Zugangsdaten

  • C#

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von EaranMaleasi.

    Korrektes, verschlüsseltes Aufbewahren von Zugangsdaten

    Ich habe einen Dienst, der sich in einem Netzwerk befindet und hin und wieder Anfragen von einem Client bearbeiten muss. Um diese Anfragen zu bearbeiten greift der Dienst auf eine Datenbank zu. Dienst, Client und Datenbank befinden sich auf jeweils eigenen Maschinen. Client, Dienst und Datenbank müssen jeweils auf einer eigenen Maschine laufen, daran kann absolut nichts geändert werden.

    Dieser Dienst, der auf einer Maschine liegt auf die Hinz und Kunz keinen Zugriff haben, hat im Moment die Verbindungsdaten für die Datenbank in einer .json Datei gelagert, wo natürlich jeder hineinsehen kann. Dies (also das Passwort) muss nun verschlüsselt werden, da es keine Möglichkeit für den Dienst gibt, die Daten irgendwo anders abzurufen.

    Nun habe ich da an zwei Methoden gedacht, die jedoch in meinen Augen beide sehr ähnlich, und unzufriedenstellend sind.
    1. Verschlüsselung mithilfe der DPAPI. Vorteil, es ist mit einem using und den beiden Methoden Protect() und Unprotect() erledigt. Nachteil, entweder Programme die der User gestartet hat, oder aber alle Programme auf der Maschine können ebenfalls die Daten entschlüsseln. Einziger "Schutz" davor ist die optionalEntropy, die dann hardcoded ist.
    2. Verschlüsselung "von Hand" via AES. Es kann nur von meinem Programm entschlüsselt werden, jedoch ist der Schlüssel dann hardcoded.
    Beide Methoden gefallen mir nicht wirklich, jedoch sehe ich aufgrund des Aufbaus keine andere Möglichkeit. Habt ihr vielleicht noch andere Ideen, wie ich das Passwort sicher auf der Maschine ablegen kann? Wie machen das andere Programme?
    Das ewig leidige Thema, der Schlüsselaufbewahrung :D

    Ich bin dazu übergegangen bei Start meiner Programme ein Passwort abzufragen. Aus dem eingegebenen Passwort generiere ich den symetrischen Schlüssel und halte den zur Laufzeit des Programms in einer System.Security.SecureString Variable vor. Vielleicht kannst du das in abgewandelter Form in deinen Dienst mit einbauen.


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.
    @EaranMaleasi Wie sicher muss das sein?
    Je nach dem kannst Du verschiedene Geschütze auffahren.
    Eine einfache Methode findest Du hier: Einfache Methode um String zu verschlüsseln
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Sicher ist immer relativ.
    Spätestens, wenn du in deinem Programm die Daten entschlüsselst und sie dort verwendest, liegen sie unverschlüsselt im Memory.
    Auch mittels Netzwerksniffer werden die Daten sichtbar.

    Für normale Anwendungen lege ich die Daten als XML ab.
    AES-verschlüsselt und Base64-codiert.
    Als Schlüssel verwende ich den zum Passwort gehörigen Benutzernamen/Rechnernamen/Verbindungsnamen in Kombination mit dem Namen der Anwendung.

    Falls du nicht extra eine Passwortverwaltungs-Form schreiben willst:
    Eine Möglichkeit, eventuelle Änderungen in den Credentials direkt in der XML nachzuziehen, habe ich auch vorgesehen.
    Wenn beim Einlesen der Datei das Passwort mit $$ umrahmt ist, betrachte ich es als unverschlüsselt und speichere es verschlüsselt wieder ab.

    Das war bisher immer hinreichend sicher.
    Aber natürlich relativ einfach knackbar, wenn man den Code kennt oder dekompiliert.
    Wie sicher benötigst du es wirklich?
    Hacker-sicher oder Benutzer-sicher?
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „petaod“ ()

    @Yanbel

    MSDN schrieb:

    Important
    We don't recommend that you use the SecureString class for new development. For more information, see SecureString shouldn't be used on GitHub.

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Das ist gut zu wissen, danke dafür. Aber aus der Begründung geht hervor das es besser ist SecureString, anstelle von normale Strings zu verwenden. Sie sagen lediglich das SecureString nicht auf allen Plattformen funktioniert und dass das interne ByteArray des Strings häufig unverschlüsselt ist, was bei normalen Strings immer der Fall ist. Microsoft empfiehlt die Klasse nur deshalb nicht, weil sie nicht das leistet was sie suggeriert. Besser als normale String-Variablen ist sie aber in jedem Fall.


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.

    Yanbel schrieb:

    weil sie nicht das leistet was sie suggeriert
    Das ist der Knackpunkt. Daher sollte man sich gedanklich eben komplett umorientieren. In welche Richtung das dann geht, ist ja Ausgangs-/Diskussionspunkt dieses Threads. Ob ich dann wirklich was Konstruktives beitragen kann, kann ich nicht garantieren.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:

    Ob ich dann wirklich was Konstruktives beitragen kann, kann ich nicht garantieren.


    Naja, ist vielleicht auch ein vielverlangt, bei einem Thema wo sogar Großunternehmen Schwierigkeiten mit haben;) Angeblich verfügt Microsoft über eine Technologie, Private Keys sicher in einem Datenspeicher abzulegen. Genaueres über die Technologie dahinter ist nicht bekannt. Die Dinger heißen "Key Vault" und sind richtig teuer selbst in der Miete.


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Yanbel“ ()

    Verschlüsselung des RAM ist zum Glück nicht meine Aufgabe.
    Ich hab mir mal angesehen, was Xamarin so auf UWP anstellt mit ihrer SecureStorage Klasse:
    github.com/xamarin/Essentials/…rage/SecureStorage.uwp.cs

    Also DPAPI und dann in einen WinRT/UWP SettingsContainer. Naja, wenn Microsoft das "Secure" schimpft, dann soll es so sein. Ich schätze ich werde dann auch den Weg einschlagen, auch wenn er mir nicht gefällt. Immerhin hab ich dann zumindest kein Passwort hardcoded.

    @3daycliff: tut mir leid. Aus den Augen aus dem Sinn. Dein Vorschlag ist eigentlich eine wunderbare Idee, jedoch ist die Vorgabe, dass, egal wer darauf Zugriff hat, Passwörter nicht einfach im Klartext vorhanden sein dürfen. Ich behalt mir den Vorschlag im Hinterkopf, vielleicht kommt er doch noch zum Einsatz ;)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „EaranMaleasi“ ()