Freitag, 28. September 2012

Passwort Generator

Heute möchte ich einen in C# geschriebenen "Passwort Generator" vorstellen. Der Name ist vielleicht etwas irreführend, es geht darum, dass das Programm alle möglichen Passwörter einer bestimmten Länge erzeugt und speichert, sodass diese zum Beispiel für einen Brute-Force-Angriff genutzt werden können.

Der Generator ist in einer Klasse gekapselt, beim Anlegen einer Instanz davon wird ein neuer Thread gestartet, welcher die Passwörter generiert und in eine Queue (Warteschlange) schreibt. Diese kann dann von außen abgefragt werden, sodass die Erzeugung der Passwörter und ein eventuelles Benutzen der Passwörter getrennt voneinander bzw. parallel geschehen kann.
Das Erzeugen der Passwörter geschieht in der Funktion FillQueue(). Hier zählt eine Schleife von der übergebenen minimalen bis maximalen Länge des Passworts durch und nach dem Prinzip der Rekursion wird für jede dieser Stellen die Funktion SetLetter() aufgerufen.
Diese durchläuft alle möglichen Zeichen (in meinem Programm kann eingestellt werden, dass die Zeichen A-Z, a-z sowie 0-9 benutzt werden), stellt die aktuelle Position auf das aktuelle Zeichen ein und ruft die Funktion mit der nächsten Stelle auf. Ist die letzte Stelle erreicht, wird das aktuelle Passwort in die Queue geschrieben.
Über die öffentliche Funktion Dequeue() der Klasse wird das unterste Element aus der Warteschlange entfernt und zurückgegeben, auf diese Weise können die erzeugten Passwörter abgerufen werden.

Der Code:
public class PasswordGenerator
    {
        Queue<string> Results; // Warteschlange mit erzeugten Passwörtern

        bool UpperAZ; // true wenn Großbuchstaben benutzt werden sollen
        bool LowerAZ; // true wenn Kleinbuchstaben benutzt werden sollen
        bool Numbers; // true wenn Zahlen benutzt werden sollen

        int Min; // minimale Länge des Passworts
        int Max; // maximale Länge des Passworts

        const int MaxQueueSize = 30000000; // maximale Zahl von Passwörtern, die gleichzeitig in der Queue gespeichert werden dürfen (Schutz vor Speicherüberlauf)

        public PasswordGenerator(bool upperAZ, bool lowerAZ, bool numbers, int min, int max)
        {
            UpperAZ = upperAZ;
            LowerAZ = lowerAZ;
            Numbers = numbers;

            Min = min;
            Max = max;
            Results = new Queue<string>();

            // neuen Thread zur Passwortgenerierung erstellen und starten
            Thread Creator = new Thread(new ThreadStart(FillQueue));
            Creator.Start();
        }

        private void FillQueue()
        {
            // Warteschlange füllen
            for (int i = Min; i <= Max; i++)
            {
                SetLetter(i, 0, "");
            }
        }

        private void SetLetter(int length, int pos, string temp)
        {
            // aktuelle Position mit allen möglichen Zeichen füllen
            if (UpperAZ)
            {
                for (int i = 65; i <= 90; i++)
                {
                    NextStep(length, pos, temp + (char)i);
                }
            }
            if (LowerAZ)
            {
                for (int i = 97; i <= 122; i++)
                {
                    NextStep(length, pos, temp + (char)i);
                }
            }
            if (Numbers)
            {
                for (int i = 0; i <= 9; i++)
                {
                    NextStep(length, pos, temp + i.ToString());
                }
            }
        }

        private void NextStep(int length, int pos, string temp)
        {
           // Funktion zum Abschließen eines Schrittes

           // ist die Warteschlange "voll", wird der Thread pausiert
           while (Results.Count > MaxQueueSize)
               Thread.Sleep(500);

            // ist noch nicht die Endposition im Passwort erreicht, wird SetLetters() mit der nächsten Position aufgerufen
            if (pos < length - 1)
                SetLetter(length, pos + 1, temp);
            else
                // ansonsten wird das aktuelle Passwort der Warteschlange hinzugefügt
                Results.Enqueue(temp);
        }

        public string Dequeue()
        {
            // liefert das unterste Element der Warteschlange
            if (Results.Count > 0)
                return Results.Dequeue();
            else
                return "";
        }
    }
Die Initialisierung des Generators erfolgt dann über
PasswordGenerator Generator = new PasswordGenerator(true, true, true, 1, 4);
Das Abfragen eines Passwortes über
Generator.Dequeue();

1 Kommentar:

  1. Gleich wieder ans Hacken gedacht ;o)
    Na sicher kann man den auch einsetzen um sichere Passwörter zu generieren.

    Grüß dich

    AntwortenLöschen